Как в TurboMD выгрузить макеты для оперативного редактирования

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При разработке в среде 1С 7.7 многие программисты используют инструмент TurboMD. Это расширение для OpenConf, которое позволяет вносить изменения в модули и формы «на лету», без необходимости монопольного выгона пользователей и сохранения всей конфигурации. Однако стандартная функциональность TurboMD часто ограничена выгрузкой только текстов модулей и визуальных форм (диалогов). Макеты (таблицы в формате MXL) при этом остаются внутри метаданных, что затрудняет их быструю правку.

В данной статье мы подробно разберем, как расширить возможности TurboMD для работы с макетами, проанализируем программные способы подмены печатных форм и рассмотрим готовые скрипты для автоматизации этого процесса.

Проблема выгрузки макетов в TurboMD

Рассмотрим ситуацию: при нажатии стандартной комбинации клавиш Ctrl+M в TurboMD выгружаются только форма и модуль. Это происходит потому, что стандартный скрипт анализирует только первые две страницы документа в конфигураторе. Выясним причину: в архитектуре OpenConf окно редактирования объекта (например, документа или отчета) представляется как многостраничный документ, где:

  1. Страница 0 (Page 0) — это визуальный редактор формы (диалог).
  2. Страница 1 (Page 1) — это текстовый редактор модуля.
  3. Страницы со 2-й и далее — это привязанные к форме макеты (таблицы).

Для того чтобы TurboMD «увидел» макеты, нам необходимо модифицировать скрипт выгрузки, заставив его проходить циклом по всем страницам документа, начиная со второй.

Решение 1: Модификация скрипта TurboMD для выгрузки MXL

Проанализируем программный код на языке VBScript, который можно добавить в основной файл скриптов TurboMD (например, TurboMD_Artur.vbs). Этот макрос позволит выгружать все макеты активного окна в отдельные файлы.


Sub UnloadCurrentWndMXL()
    Dim w, d, page, i, name, pos
    
    Set w = Windows.ActiveWnd
    If w Is Nothing Then
        MsgBox "Нет активного окна", vbOKOnly, "TurboMD"
        Exit Sub
    End If
    
    Set d = w.Document
    If d.ID < 2 Then
        MsgBox "Окно не является ни формой, ни модулем", vbOKOnly, "TurboMD"
        Exit Sub
    End If
    
    ' Вызываем анализ файла настроек turbomd.prm
    AnalyzeTurboMDPrm 1
    
    ' Проверяем тип документа. Если это воркбук (форма с макетами)
    If d = docWorkBook Then 
        ' Начинаем цикл со второй страницы (индекс 2), где лежат макеты
        For i = 2 To d.CountPages - 1
            Set page = d.Page(i)
            ' Проверяем, является ли страница таблицей
            If page = docTable Then
                name = page.name
                pos = InStrRev(name, ".")
                ' Формируем имя файла на основе имени страницы
                name = Left(name, pos-1) & "." & d.NamePage(i)
                ' Выгружаем макет в файл через вспомогательную процедуру
                UnloadDoc page, name 
            End If
        Next
    End If
    
    ' Сохраняем обновленные привязки в turbomd.prm
    WriteToTurboMDPrm 1
End Sub

Важное замечание: процедура UnloadDoc должна уметь обрабатывать передаваемое имя. Если ваша версия скрипта принимает только один параметр, убедитесь, что вы адаптировали вызов под свою реализацию. Рассмотрим более полную версию структуры автоматизации выгрузки ниже.

Полный скрипт автоматизации для OpenConf

Для полноценной работы нам потребуется набор вспомогательных функций, которые будут создавать каталоги на диске и прописывать пути в файл TurboMD.prm. Разберем комплексный пример:


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

' Функция создания структуры папок на диске
Sub MakeDir(Dir)
    Set fso = CreateObject("Scripting.FileSystemObject")
    ' Обработка сетевых путей UNC и локальных дисков
    ' ... (логика перебора папок)
    If fso.FolderExists(p) = False Then fso.CreateFolder p
End Sub

' Процедура выгрузки конкретного документа (текста или таблицы)
Sub UnloadDoc(doc, Name)
    fName = Replace(Name, ".", "\")
    ' Определяем расширение файла: mxl для таблиц, txt для модулей
    If doc = docTable Then 
        fName = fName & ".mxl" 
    Else 
        fName = fName & ".txt"
    End If
    
    FullName = BaseDir & fName
    lastdec = InStrRev(FullName, "\")
    Dir = Left(FullName, lastdec - 1)
    
    MakeDir Dir ' Создаем папку, если ее нет
    doc.SaveToFile FullName ' Сохраняем объект метаданных во внешний файл
    
    ' Добавляем информацию о подмене в список для TurboMD.prm
    AddDocToList Name, "unpack\" & fName
End Sub

Используя данный подход, мы получаем возможность редактировать MXL файл обычным редактором или в другом сеансе 1С, а текущий сеанс будет подхватывать изменения моментально.

Решение 2: Программная подмена макета в коде 1С

Если вы не хотите глубоко внедряться в скрипты OpenConf, можно реализовать механизм «внешних макетов» непосредственно в коде конфигурации. Этот метод основан на использовании функции ИсходнаяТаблица(), которая в 1С 7.7 позволяет загружать макет из внешнего файла.

Рассмотрим пример функции, которая ищет MXL файл в специальном каталоге ExtMXL внутри информационной базы. Если файл найден — используется он, если нет — используется стандартный макет из метаданных.


Функция ПолучитьТаблицуMXL(Знач ИмяМакета="", Знач ПоУмолчанию="") Экспорт
    ИмяМакета = СокрЛП(?(ПустаяСтрока(ИмяМакета)=1, ПоУмолчанию, ИмяМакета));
    // Добавляем расширение, если оно не указано
    Если Найти(ВРег(ИмяМакета), ".MXL") = 0 Тогда
        ИмяМакета = ИмяМакета + ".MXL";
    КонецЕсли;
    
    // Ищем во внешнем каталоге базы
    КаталогВнешнихМакет = КаталогИБ() + "ExtMXL\";
    ФайлТаблицы = КаталогВнешнихМакет + ИмяМакета;
    
    Если ФС.СуществуетФайл(ФайлТаблицы) = 1 Тогда
        Возврат ФайлТаблицы; // Возвращаем путь к внешнему файлу
    Иначе
        Возврат ПоУмолчанию; // Возвращаем имя макета в конфигурации
    КонецЕсли;
КонецФункции

Посмотрим на практическое применение этой функции при формировании печатной формы документа:


Процедура Печать()
    Таб = СоздатьОбъект("Таблица");
    // Пытаемся взять внешнюю форму "ПриходнаяНакладная.mxl"
    ФайлМакета = ПолучитьТаблицуMXL("ПриходнаяНакладная");
    
    // Метод ИсходнаяТаблица одинаково принимает как имя макета, так и путь к файлу
    Таб.ИсходнаяТаблица(ФайлМакета);
    
    Таб.ВывестиСекцию("Шапка");
    // ... дальнейший код печати
    Таб.Показать();
КонецПроцедуры

Этот способ крайне эффективен, так как позволяет обновлять печатные формы у пользователей на лету, просто копируя новый MXL файл в папку ExtMXL, без внесения изменений в MD файл.

Рекурсивный поиск файлов

В некоторых случаях макеты могут быть разнесены по подпапкам. Для этого удобно использовать рекурсивную функцию поиска. Проанализируем пример такой функции, которая использует объект ФС (Файловая Система):


Функция РекурсивныйПоискФайла(Знач ТекущийКаталог, ИмяФайла) Экспорт
    ТекущийКаталог = СокрЛП(ТекущийКаталог);
    Если Прав(ТекущийКаталог, 1) <> "\" Тогда
        ТекущийКаталог = ТекущийКаталог + "\";
    КонецЕсли;

    // Проверяем наличие файла в текущей папке
    Если ФС.СуществуетФайл(ТекущийКаталог + ИмяФайла) = 1 Тогда
        Возврат ТекущийКаталог + ИмяФайла;
    КонецЕсли;

    // Если не нашли, перебираем подкаталоги
    ОбъектФС = СоздатьОбъект("ФС");
    Файл = ОбъектФС.НайтиПервыйФайл(ТекущийКаталог + "*.*");
    Пока ПустаяСтрока(Файл) = 0 Цикл
        // Игнорируем системные переходы "." и ".."
        Если Лев(Файл, 1) <> "." Тогда
            Атрибуты = "";
            ОбъектФС.АтрибутыФайла(ТекущийКаталог + Файл, , Атрибуты);
            ЭтоКаталог = Число(Сред(Атрибуты, 4, 1));
            
            Если ЭтоКаталог = 1 Тогда
                // Рекурсивный вызов для вложенной папки
                НайденныйПуть = РекурсивныйПоискФайла(ТекущийКаталог + Файл, ИмяФайла);
                Если ПустаяСтрока(НайденныйПуть) = 0 Тогда
                    Возврат НайденныйПуть;
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
        Файл = ОбъектФС.НайтиСледующийФайл();
    КонецЦикла;
    Возврат "";
КонецФункции

Дополнительные инструменты: GComp и Йоксель

Помимо TurboMD, существуют и другие мощные инструменты для работы с макетами вне конфигуратора:

Борьба с «грязным» MD-файлом

Одной из проблем при работе с TurboMD является то, что конфигуратор помечает файл метаданных как измененный (флаг Dirty), даже если вы правите только внешние файлы. Из-за этого при закрытии программа настойчиво предлагает сохранить изменения. Для решения этой проблемы опытные разработчики используют дополнительные макросы для OpenConf, которые программно сбрасывают флаг модификации конфигурации, позволяя закрыть конфигуратор без лишних вопросов и без фактического изменения MD файла.

Подведем итог: для оперативной работы с макетами в TurboMD лучше всего использовать модифицированный VBS-скрипт, который учитывает все страницы документа docWorkBook. В дополнение к этому, внедрение обертки над функцией ИсходнаяТаблица() в коде 1С позволит вам и вашим коллегам редактировать печатные формы без прерывания работы пользователей.

← На главную