Книга знаний

1С:Предприятие / Приемы программирования / Внешние компоненты

ТурбоМД: решение проблемы загрузки мокселей

С использованием 1С++Автор статьи: jbond | Редакторы:
Последняя редакция №4 от 31.05.10 | История
URL: http://kb.mista.ru/article.php?id=222

Ключевые слова: ТурбоМД, TurboMD, Моксель, динамическая, загрузка


ВК ТурбоМД (Книга знаний: OpenConf: пишем скрипты для конфигуратора 1С 7.7 (статья)) позволяет работать с динамической загрузкой модулей и форм.
С выгруженными мокселями(шаблонами таблиц) он работать не умеет.

Для решения проблемы подгрузки шаблонов MXL, выгруженных с помощью скрипта TurboMD.vbs используйте
следующую технику.
Вам понадобится ВК 1С++ (www.1cpp.ru) версии 2.0.2:

Создайте класс-наследник от Таблица с методом

class ТаблицаТМБ = ТаблицаТМБ.ert: Таблица
{
Число ИсходнаяТаблица (Строка Имя, Строка Путь="");
}

// начало класса Wizard1C++ 
// ТаблицаТМБ
//TODO:
//Совместимость с 1С++ 1.8.0.2 (там не было в пути /Форма) - сделано
Перем РФ; //: РасширениеФормы
Перем ВремяМД;

Перем КаталогТМД Экспорт;

//------------------------------------------------------------------------------
Функция        GetThis(Конт)     Возврат Конт;                     КонецФункции //: Контекст
Функция     Этот()             Возврат GetThis(Контекст);        КонецФункции //: Контекст
//------------------------------------------------------------------------------

//******************************************************************************
//
Функция ВремяПоследнЗаписи(ИмяФайла)
    Перем ВремяПоследнЗаписи;
    ФС.АтрибутыФайла(ИмяФайла,,,,,ВремяПоследнЗаписи);
    Возврат ВремяПоследнЗаписи;
КонецФункции

//------------------------------------------------------------------------------
Процедура Конструктор()
    РФ = СоздатьОбъект("РасширениеФормы");
    КаталогБД = СокрЛП(КаталогИБ());
    КаталогТМД = КаталогБД + "unpack\";
    ВремяМД = ВремяПоследнЗаписи(КаталогБД + "1Cv7.MD");
КонецПроцедуры // Конструктор

//******************************************************************************
//
Функция ПолучитьПутьТаблица(Имя)
    Если ФС.СуществуетФайл(Имя) = 0 Тогда
        РФ.УстановитьФорму(Этот().ПолучитьКонтекстОкружения().Форма);
        ПутьВнешнийШаблон = КаталогТМД + СтрЗаменить(РФ.ПолныйТипОбъекта(),".","\");
        Если  СтрЧислоВхождений(ПутьВнешнийШаблон,"Форма") = 0 Тогда
            ПутьВнешнийШаблон = ПутьВнешнийШаблон + "\Форма"
        КонецЕсли;
        ПутьВнешнийШаблон = ПутьВнешнийШаблон + "\" + Имя + ".mxl";
        Если ФС.СуществуетФайл(ПутьВнешнийШаблон) <> 0 Тогда  // Если таблица формы выгружалась
            Если ВремяПоследнЗаписи(ПутьВнешнийШаблон) > ВремяМД Тогда
                Возврат ПутьВнешнийШаблон;
            КонецЕсли
        КонецЕсли
    КонецЕсли;
    
    Возврат Имя;
КонецФункции

//******************************************************************************
//
Функция ИсходнаяТаблица(Имя, Путь) Экспорт
    База = Этот().ПолучитьБазовыйКласс("Таблица");
    Если ПустаяСтрока(Путь) = 1 Тогда
        База.ИсходнаяТаблица(ПолучитьПутьТаблица(Имя));
        Возврат 2;
    Иначе  //Вариант для версии FormEx 2.0.2
        Возврат База.ИсходнаяТаблица(Имя, Путь);
    КонецЕсли;
КонецФункции // ИсходнаяТаблица()

//******************************************************************************
//
Функция  SourceTable (Имя, Путь) Экспорт
    Возврат ИсходнаяТаблица(Имя, Путь)
КонецФункции // ИсходнаяТаблица()

// завершение класса Wizard1C++ !!



Использование:
Таб = СоздатьОбъект("ТаблицаТМБ");
Таб.ИсходнаяТаблица("Печать");

Теперь метод ИсходнаяТаблица будет пытаться загрузить шаблон, выгруженный с помощью скрипта ТубоМД::UnloadCurrentWnd.

Текст скрипта OpenConf:
' (c) Orefkov
'Пример скрипта, позволяющего выгрузить в файл
'текущую редактируемую форму, модуль или таблицу
'(либо просто модуль проведения или вида расчета)
'во внешний файл.
'При этом выгружается текущее состояние формы/модуля
'без необходимости сохранять конфигурацию
'
' Автор: Александр Орефков
'
' artbear: Есть вставка кода
' Автор - Николай Гаврилов <shootnick2000@mail.ru>
' Отлавливает момент сохранения md и переименовывает turboMD.prm в bak.
'Обобщение наработок сделанных другими пользователями
' + дополнительно сохранение мокселей формы
' 

Dim BaseDir
BaseDir = IBDir & "unpack\" ' Базовый каталог для выгрузки

Dim TurboMdPrmName
TurboMdPrmName = IBDir & "TurboMd.prm"

Dim Collection

Sub ExitAll()
    StopFile="stop.all"
    Set FSO = CreateObject("Scripting.FileSystemObject")
       Set tf = FSO.CreateTextFile (IBDir & StopFile)
       tf.Close
End Sub

' Процедура создания ветки каталогов
Sub MakeDir(Dir)
    Set FSO = CreateObject("Scripting.FileSystemObject")
    If Left(Dir, 2) = "\\" Then
        'UNC Path
        pos = InStr(3, Dir, "\")    'Server name
        p = Left(Dir, pos)
        Dir = Mid(Dir, pos + 1)
    Else
        p = ""
    End If
    pos = 1
    While pos <> 0
        pos = InStr(Dir, "\")
        If pos = 0 Then
            p = p & Dir
        Else
            p = p & Left(Dir, pos)
            Dir = Mid(Dir, pos + 1)
        End If
        If FSO.FolderExists(p) = False Then FSO.CreateFolder p
    Wend
End Sub

' функции работы со списком модулей
Sub AddDocToList(ModuleName, FileName)
        if Collection.Exists(ModuleName) then
            Collection.Remove ModuleName
        end if
        Collection.Add ModuleName, FileName
end sub 'AddDocToList

Sub RemoveDocFromList(doc)
        if Collection.Exists(doc.Name) then
            Collection.Remove doc.Name
        end if
End Sub 'RemoveDocFromList()

' Анализ файла turbomd.prm
Sub AnalyzeTurboMDPrm(NullParam) ' параметр нужен, чтобы не был виден в списке макросов
    set Collection = CreateObject("Scripting.Dictionary")

    Set fso = CreateObject("Scripting.FileSystemObject")
    set file = fso.OpenTextFile(TurboMdPrmName, 1, true) 'чтение

        Do While file.AtEndOfStream <> True
      CurrLine = file.ReadLine
      pos = InStr(CurrLine,"=")
      if pos <> 0 then
          ModuleName = Left(CurrLine, pos-1)
          FileName = Mid(CurrLine, pos+1)
          AddDocToList ModuleName, FileName
            end if
        Loop
        file.Close
end sub 'AnalyzeTurboMDPrm

' добавление соответствия в файл TurboMD.prm
Sub WriteToTurboMDPrm(NullParam)
    Set fso = CreateObject("Scripting.FileSystemObject")
    set file = fso.CreateTextFile(TurboMdPrmName, 2) 'запись

        items = Collection.Items
        keys = Collection.Keys
        For i = 0 To Collection.Count -1
            file.WriteLine keys(i) & "=" & items(i)
        Next
        file.Close
end sub 'WriteToTurboMDPrm

'Выгрузка документа
Sub UnloadDoc(doc,docName)
    fName = BaseDir & Replace(doc.Name, ".", "\")
    'Из имени файла выделяем каталог
    lastdec = InStrRev(fName, "\")
    Dir = Left(fName, lastdec - 1)
    MakeDir Dir    
    If docName <> "" Then
        fName = Left(fName, lastdec) & docName
    End If
    'И создаем этот каталог
    If doc = docTable Then ' Если выгружаемый объект - таблица
        fName = fName & ".mxl"
    Else
        fName = fName & ".txt"
    End If
    ' Выгружаем документ в файл
    doc.SaveToFile fName
    AddDocToList doc.Name, fName
End Sub

'Собственно макрос для выгрузки активного окна
Sub UnloadCurrentWnd()
    Set w = Windows.ActiveWnd
    On Error Resume Next
    If w Is Nothing Then
        MsgBox "Нет активного окна", vbOKOnly, "TurboMD"
        Exit Sub
    End If
    
    Set d = w.document    
    If d.ID < 2 And d.Name<>"Глобальный модуль" Then
        MsgBox "Окно ни форма, ни модуль", vbOKOnly, "TurboMD"
        Exit Sub
    End If
    
    'анализ файла turbomd.prm
    AnalyzeTurboMDPrm 1            
    
    If d = docText Then     ' Просто модуль
        UnloadDoc d,""
    Else
        If d = docWorkBook Then ' Форма
        For i = 0 To d.CountPages-1
                 UnloadDoc d.Page(i),d.NamePage(i)
             Next
        End If
    End If
    WriteToTurboMDPrm 1
End Sub

Sub ClearAllLinks () 'чтобы все загружалось из мд
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set file = fso.CreateTextFile(TurboMdPrmName, 2) 'запись
    file.Write ""
End Sub

'Макрос для загрузки всех распакованных файлов обратно в мдшник
Sub LoadFromFilesToMD()
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Set f = FSO.OpenTextFile(IBDir & "turbomd.prm", 1, True)
    On Error Resume Next
    While f.AtEndOfStream = False
        t = f.ReadLine()
        eq = InStr(t, "=")
        If eq > 0 Then
            dName = Trim(Left(t, eq - 1))
            fName = Trim(Mid(t, eq + 1))
            If Mid(fName, 2, 1) <> ":" And Left(fName, 2) <> "\\" Then fName = IBDir & fName
            Set doc = Documents(dName)
            If Err <> 0 Then
                Message Err.Description, mRedErr
                Err.Clear
            Else
                If doc.LoadFromFile(fName) <> True Then
                    Message "Не удалось загрузить " & doc.Name & " из " & fName, mBlackErr
                Else
                    Message doc.Name & " загружен из " & fName, mInformation
                End If
                If Err <> 0 Then
                    Message Err.Description, mRedErr
                    Err.Clear
                End If
            End If
        End If
    Wend
End Sub

' Макрос для быстрого открытия файла TurboMD.prm
Sub OpenTurboMDPrm()
    Documents.Open IBDir & "turbomd.prm"
End Sub

'color.vbs
Sub SelectColor()
Set doc = Windows.ActiveWnd.Document
If doc = docWorkBook Then Set doc = doc.Page(1)

If doc <> docText Then Exit Sub
If not doc.IsOpen Then Exit Sub

SelValue = doc.Range(doc.SelStartLine, doc.SelStartCol, doc.SelEndLine, doc.SelEndCol)

set CD = CreateObject("MSComDlg.CommonDialog")
CD.Flags = 3
CD.CancelError = 1
If SelValue = "" Then
Else
CD.Color = doc.Range(doc.SelStartLine, doc.SelStartCol, doc.SelEndLine, doc.SelEndCol)
End If

On Error Resume Next
CD.ShowColor()
if Err.Number > 0 Then Exit Sub

doc.Range(doc.SelStartLine, doc.SelStartCol, doc.SelEndLine, doc.SelEndCol) = CD.Color
End Sub 

Sub SaveMD()
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Set srv = CreateObject("Svcsvc.Service")
    SaveFolder = srv.SelectFolder("Сохранить в:")
    If FSO.FolderExists(SaveFolder) Then
        MetaData.SaveMDToFile SaveFolder & "\1cv7new.md", False
    End If
End Sub

'/////////////////////////////////////////////////////////////// 
Sub Configurator_OnMsgBox(Text, Style, DefAnswer, Answer) 
'Делаем так, чтобы 1С-ка не задавала много лишних вопросов 
       If InStr(Text, "Сохранить изменения?") <> 0 Then 
          Answer=DefAnswer 
       End If 
       If InStr(Text, "Реорганизация информации закончена!") <> 0 Then 
          Answer=DefAnswer 
       End If 
       If InStr(Text, "Выполнить сохранение метаданных?") <> 0 Then 
          Set FSO = CreateObject("Scripting.FileSystemObject")
          FSO.CopyFile IBDir & "1cv7.md", IBDir & "1cv7.md.bak", True
          Answer=DefAnswer 
       End If 
End Sub

'///////////////////////////////////////////////////////////////
Sub Configurator_ConfigWindowCreate 
    'Загружаем все текстовички при открытии конфигурации 
    
    'Call LoadFromFilesToMD
End Sub

'/////////////////////////////////////////////////////////////// 
Sub Configurator_MetaDataSaved(FileNAme)
    StopFile="stop.all"
    Set FSO = CreateObject("Scripting.FileSystemObject")
    If FSO.FileExists(IBDir & StopFile) Then
        FSO.DeleteFile IBDir & StopFile
    End if
    
    path = fso.GetParentFolderName(FileName) 
    path = LCase(path) 
    
    If InStr(path, "new_stru") <> 0 Then 
    'При изменении структуры метаданных (например, я создал новую константу) 
    'папка почему-то NEW_STRU 
        path = fso.GetParentFolderName(path) 
    End If 
    
    fname = path+"\turbomd.prm" 
    bakname = path+"\turbomd.bak" 
    
    if fso.FileExists(bakname) then 
        fso.DeleteFile bakname, true
    end if 
    
    if fso.FileExists(fname) then 
        fso.MoveFile fname, bakname 
    end if
End Sub


Вероятно, это самый "правильный" вариант. Он должен работать и на старых версиях 1С++ (>=1.8)

Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2025 | Mista.ru

Яндекс.Метрика