Как расширить функционал пользовательского интерфейса и системное взаимодействие 1С 7.7 с помощью компоненты FormEx, а также решать возникающие технические проблемы?

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

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

Расширение возможностей таблиц 1С (ТЗ и МСЧ)

Компонента FormEx предоставляет значительные улучшения для работы с таблицами значений (ТЗ) на формах и многострочными частями (МСЧ) документов и справочников, что позволяет создавать более удобные и интерактивные интерфейсы.

  1. Копирование, удаление и вставка областей ячеек

    Для эффективной работы с данными в таблицах, FormEx предлагает методы для манипуляций с областями ячеек. Метод КопироватьОбластьТаблицы позволяет перенести данные из одной таблицы в другую, а методы УдалитьОбластьТаблицы и ВставитьОбластьТаблицы обеспечивают гибкое управление структурой таблицы. Мы видим, что эти методы значительно упрощают программное изменение табличных данных.

    
    КопироватьОбластьТаблицы(<ТаблицаИсточник>,<СтрокаНачальная>,<КолонкаНачальная>,<СтрокаКонечная>,<КолонкаКонечная>,<ТаблицаПриемник>,<СтрокаНачальнаяПриемника>,<КолонкаНачальнаяПриемника>)
    УдалитьОбластьТаблицы(<Таблица>,<СтрокаНачальная>,<КолонкаНачальная>,<СтрокаКонечная>,<КолонкаКонечная>,<НаправлениеСдвигаЯчеек>)
    ВставитьОбластьТаблицы(<Таблица>,<СтрокаНачальная>,<КолонкаНачальная>,<СтрокаКонечная>,<КолонкаКонечная>,<НаправлениеСдвигаЯчеек>)
    

    При использовании этих методов важно учитывать, что удаление строк, содержащих активную ячейку, может приводить к зависанию 1С. Разработчик FormEx предложил исправление, устраняющее эту проблему, особенно в ситуациях, когда таблица содержит объединенные ячейки или работает в нестандартном окружении. Проверяйте, что используете актуальную версию компоненты.

  2. Центрирование текущей строки

    Для улучшения пользовательского опыта при работе с длинными списками, FormEx позволяет автоматически центрировать текущую строку в таблице при ее изменении. Изначально это было реализовано глобальным методом Сервис::ЦентрироватьТаблицуДляТекущейСтроки(). Однако для более гибкой настройки, разработчик предложил использовать специальную служебную колонку с идентификатором "FormEx_ПараметрыТаблицы", в заголовке которой можно указать параметры центрирования.

    
    тз.НоваяКолонка("Название",,,,"Название заголовка");
    тз.НоваяКолонка("FormEx_ПараметрыТаблицы",,,,"ЦентрироватьТекущуюСтроку:0");
    тз.ВидимостьКолонки("FormEx_ПараметрыТаблицы", 0);
    

    Параметр после двоеточия (например, :0) определяет тип центрирования: 0 — низ, 1 — центрировать, 2 — верх. Такой подход позволяет индивидуально настраивать поведение для каждой таблицы.

  3. Управление шрифтами и отображение изображений

    FormEx предоставляет расширенные возможности по управлению шрифтами в таблицах. Однако возникали проблемы с некорректным отображением шрифтов ("кракозябры") и неточным определением размера шрифта при использовании метода Сервис.СоздатьШрифт(). Разработчик внес исправления, позволяющие корректно парсить параметры шрифтов из системных настроек и создавать жирные шрифты на основе существующего шрифта формы.

    
    // Пример создания жирного шрифта на основе шрифта кнопки
    ФормаРасш = СоздатьОбъект("РасширениеФормы");
    ШрифтФормы = ФормаРасш.кнЗакрыть.Шрифт;
    КодШрифт = глСервис.СоздатьШрифтНаОсновании(ШрифтФормы,,,7); // 7 - флаг жирного шрифта
    

    Теперь также можно отображать изображения непосредственно в ячейках таблицы значений с помощью макроса IMAGE[] в плане раскраски. Например, IMAGE[5] будет выводить картинку с номером 5 из установленного для таблицы набора пиктограмм. При этом, если текст в ячейке присутствует, изображение будет располагаться слева от текста; если текста нет, изображение будет центрировано.

  4. Многострочные заголовки колонок

    Для повышения информативности таблиц, FormEx позволяет создавать многострочные заголовки колонок, используя символ РазделительСтрок. Это особенно полезно для таблиц со множеством колонок, где необходимо вместить длинные названия.

    
    Процедура ПослеОткрытия()
        РФ = СоздатьОбъект("РасширениеФормы");
        АФ = РФ.ПолучитьАтрибут("ИдКолонки"); // ИдКолонки - текстовый идентификатор колонки
        АФ.Заголовок = "Первая строка"+РазделительСтрок+"Вторая строка";
    КонецПроцедуры
    
  5. Оптимизация таблиц

    FormEx позволяет регулировать ширину системных колонок, например, колонки "НомерСтроки" в списках справочников, которая по умолчанию может быть избыточно широкой. Используйте метод УстановитьШиринуКолонки() для настройки этих параметров, что улучшит визуальное восприятие и компоновку форм.

Улучшения пользовательского интерфейса

FormEx значительно расширяет возможности взаимодействия с пользовательским интерфейсом 1С 7.7, добавляя функционал, недоступный в стандартной поставке.

  1. Открытие стандартных окон и движений

    Метод Сервис::ОткрытьДвиженияОбъекта(<Документ>) предоставляет удобный способ открытия стандартного окна движений документа по регистрам, имитируя действие "Движения документа" из контекстного меню. Это упрощает навигацию по связанным данным. Также существует альтернативный способ открытия системных окон с помощью VBScript и SendMessage, что может быть полезно для вызова других системных функций 1С, например, списка пользователей.

    
    Процедура ОткрытьСистемноеОкно(КодОкна) Экспорт
        ТекстМодуля = "
        |Public Const WM_COMMAND = &h111
        |Public Sub GetUsersWindow()
        |    Set Wrap = CreateObject(""DynamicWrapperX"")
        |    Wrap.Register ""USER32"", ""GetForegroundWindow"", ""f=s"", ""r=l""
        |    Wrap.Register ""user32"", ""SendMessage"" , ""i=hull"" , ""r=l""
        |    Res = Wrap.SendMessage(Wrap.GetForegroundWindow(), WM_COMMAND, "+КодОкна+", 0)
        |End Sub";
        мScrptCtrl = СоздатьОбъект("MSScriptControl.ScriptControl");
        мScrptCtrl.Language = "vbscript";
        мScrptCtrl.AddCode(ТекстМодуля);
        мScrptCtrl.CodeObject.GetUsersWindow();
    КонецПроцедуры
    
    // Пример использования для открытия движений регистров документа
    ОткрытьСистемноеОкно(32880); 
    

    Попытки передать конкретный регистр для открытия движений напрямую в ОткрытьДвиженияОбъекта не увенчались успехом, так как это требует глубокой переработки внутренних функций движка 1С.

  2. Динамические панели в строке состояния

    FormEx позволяет добавлять пользовательские панели в строку состояния главного окна 1С. Объект ПанельСтрокиСостояния предоставляет атрибуты Идентификатор, Наименование, Заголовок и Ширина. Это дает возможность выводить актуальную информацию (например, курсы валют, статусы системы) непосредственно в интерфейс.

    
    Перем ПанельСостояния;
    
    Процедура ПриНачалеРаботыСистемы()
        // ... загрузка FormEx ...
        ПанельСостояния = СоздатьОбъект("ПанельСтрокиСостояния");
        КодНовойПанели = ПанельСостояния.ДобавитьПанель("МояПанель1","Статус: Ок",100,0,1);
        // 0 - положение по умолчанию, 1 - с автоподгонкой ширины
    КонецПроцедуры
    
    Процедура МояПроцедураОбработчикаОжидания()
        Если ПанельСостояния.ПолучитьПанельПоИД("МояПанель1") = 1 Тогда
            ПанельСостояния.Заголовок = "Время: " + ТекущееВремя();
        КонецЕсли;
    КонецПроцедуры
    

    Также предусмотрена предопределенная процедура ПриДвойномНажатииЛевойКнопкиВСтрокеСостояния(), которая позволяет реагировать на действия пользователя с этими панелями. При начальной реализации были выявлены ошибки, когда добавление новой панели удаляло системные, но они были оперативно устранены в последующих версиях.

  3. Дерево-таблица с флажками

    Для объектных списков FormEx предлагает функционал добавления флажков в дерево-таблицу. Если в таблице-основе присутствует колонка с именем "Пометка" (или "Check"), компонент автоматически добавляет бокс для пометки рядом с пиктограммой. Изменения пометки отражаются в данной колонке, и для контроля за ними вызывается событие ПриПометкеУзла(<НомерСтроки>,<УстанавливаемоеЗначение>,<ФСО>), в котором можно отменить действие.

  4. GUI-идентификаторы

    FormEx предоставляет возможность получить GUID объекта без фигурных скобок, что часто требуется для различных интеграций и формирования строк. Метод ПолучитьGUID(Режим) позволяет управлять форматом вывода: 0 (по умолчанию) возвращает GUID со скобками, любое другое значение – без скобок.

    
    // Получить GUID со скобками
    GUIDСоСкобками = глСервис.ПолучитьGUID(); 
    
    // Получить GUID без скобок
    GUIDБезСкобок = глСервис.ПолучитьGUID(1);
    
  5. Обои главного окна

    FormEx имеет недокументированную, но очень удобную функцию: если в каталоге информационной базы разместить файл wallpaper.bmp, он будет использован в качестве обоев главного окна 1С. Кроме того, в имени файла можно указать положение обоев в скобках (например, "wallpaper(6).bmp" для растягивания на все окно или "wallpaper(2).bmp" для размещения в правом верхнем углу).

  6. Встраивание PDF-просмотрщика

    Хотя FormEx не имеет встроенного PDF-просмотрщика, мы можем использовать ActiveX-компоненты для этой цели. Например, можно встроить Adobe Acrobat Reader (AcroPDF.PDF.1) или Microsoft Web Browser (Shell.Explorer.2) в форму 1С, что позволит отображать PDF-документы прямо в приложении. Для управления размещением такого элемента может потребоваться вспомогательный класс 1С++ для привязок.

    
    // Пример использования ActiveX Shell.Explorer.2 для отображения PDF
    // Предполагается, что на форме есть элемент управления с идентификатором "Ридер"
    Процедура ПослеОткрытия()
        Ридер = СоздатьЭУ("Shell.Explorer.2"); 
        Ридер.Navigate("C:\ПутьКДокументу.pdf");
    КонецПроцедуры
    

Решение системных и специфических проблем

В процессе эксплуатации 1С 7.7 с FormEx могут возникать различные системные проблемы, требующие диагностики и специфических решений.

  1. Отмена системных команд и F1

    FormEx позволяет перехватывать системные команды, поступающие в главное окно 1С, с помощью предопределенной процедуры ПриПолученииКомандыГлавнымОкном(wParam, lParam). Это дает возможность блокировать или изменять стандартное поведение 1С. Например, можно отменить вызов справки по клавише F1 или запретить выполнение команды печати.

    
    Процедура ПриПолученииКомандыГлавнымОкном(wParam, lParam, ФлВозврата) Экспорт
        // Коды команд: 57670 (F1), 57666 (Shift+F1), 32808 (О системе 1С-Предприятие)
        Если (wParam = 57670) Или (wParam = 57666) Тогда
            Сообщить("Справка отключена для пользователя!");
            ФлВозврата = 0; // Отмена стандартной обработки
        КонецЕсли;
    
        // Если стандартная обработка еще не отменена
        Если ФлВозврата = 1 Тогда
            // Возможно, выполнить оригинальное событие ГМ
            // Перехватчик.ВыполнитьОригинальноеСобытиеГлобальногоМодуля("ПриПолученииКомандыГлавнымОкном", wParam, lParam, ФлВозврата);
        КонецЕсли;
    КонецПроцедуры
    

    Для отмены стандартной обработки необходимо установить параметр ФлВозврата в 0. Эта функция критически важна для создания управляемого пользовательского окружения.

  2. Стабильность и ошибки загрузки FormEx

    Некоторые версии FormEx могли вызывать падения 1С 7.7 при загрузке, особенно на старых версиях Windows Server 2003 или специфических сборках Windows 10/11. Ошибки часто указывали на модули mfc42.dll или unknown. В ходе анализа было выявлено, что причиной могли быть особенности обработки сообщений Windows (использование CallWindowProc вместо прямого вызова WNDPROC) и порядок инициализации внутренних классов FormEx. Разработчик предоставил тестовые сборки с логированием для локализации проблем, и в конечном итоге эти проблемы были исправлены. Для стабильной работы на современных ОС может также потребоваться добавление 1cv7.exe в исключения DEP (Data Execution Prevention).

  3. Взаимодействие с внешними событиями (сканеры) и модальные окна

    В 1С 7.7 существует проблема, когда внешние события (например, от сканера штрихкодов) могут "проваливаться" за активные модальные окна или вызывать зависания системы. Это происходит из-за асинхронной природы обработки внешних событий. Для решения этой проблемы рекомендуется временно отключать прием данных от сканера перед открытием модального окна и восстанавливать его после закрытия.

    
    // Пример использования для ВвестиЧисло()
    глМожноработатьОбработчикуПроцессов = 0; // Флаг для ОбработкиОжидания
    глСканерПосылкаДанных(0); // Отключаем прием данных от сканера
    
    Если ВвестиЧисло(СуммаБонусаЗапросА, "Введите сумму бонусов", 10, 2, 60) = 0 Тогда
        СуммаБонусаЗапросА = 0;
    КонецЕсли;
    
    глСканерПосылкаДанных(1); // Включаем прием данных
    глМожноработатьОбработчикуПроцессов = 1; // Включаем ОбработкуОжидания
    

    Если же необходимо обрабатывать внешние события внутри модальной формы, следует создавать собственные модальные формы с процедурой ОбработкаВнешнегоСобытия() и управлять передачей событий вручную.

  4. Проблема 2038 года в 1С 7.7

    Платформа 1С 7.7, особенно ее DBF-версия, столкнется с проблемой 2038 года (Year 2038 problem), связанной с использованием 32-битного типа time_t для хранения времени. Начиная с 19 января 2038 года, 32-битные представления времени могут переполниться, что приведет к некорректной работе с датами. 1С 7.7 содержит явную проверку, которая блокирует запуск приложения, если системная дата превышает 2037 год. Сообществом были разработаны патчи (например, V72038Patch для 1cv7.exe и bkend.dll), позволяющие обойти эту проверку. Однако следует учитывать, что внутренние механизмы работы с датами могут потребовать дополнительных модификаций, особенно в SQL-версиях, где CDate хранит даты в днях, а не в юникстайм.

  5. Получение информации о системе (MAC-адреса, версия ОС)

    FormEx позволяет получить расширенную информацию об операционной системе и сетевых адаптерах. Метод Сервис::ВерсияОС() может быть дополнен для возврата MAC-адресов всех сетевых адаптеров, предоставляя эту информацию в виде таблицы значений. Это удобно для идентификации рабочих станций и управления лицензиями или доступом.

    
    Параметры = "";
    глСервис.ВерсияОС(Параметры); // Параметры будет списком значений
    Адаптеры = Параметры.Получить("Adapters");
    Если ТипЗначенияСтр(Адаптеры) = "ТаблицаЗначений" Тогда
        // Обработка таблицы значений с информацией об адаптерах
        // Каждая строка ТЗ содержит: Имя, MACAddress, IPAddress, ...
        глПечатьТЗ(Адаптеры); // Пример вывода ТЗ
    КонецЕсли;
    
  6. Печать штрихкодов

    Для генерации штрихкодов FormEx предоставляет метод глСервис.НарисоватьШтрихкод(), позволяющий выводить штрихкоды различных типов (например, EAN-13) на макете в элементе "Рисунок". Возникали вопросы по масштабированию и чтению таких штрихкодов сканерами, особенно на маленьких ценниках. Рекомендуется экспериментировать с типом штрихкода (например, Code39) и размером области "Рисунка", а также убедиться, что светлые зоны до и после штрихкода достаточны. Если стандартные масштабы (например, 70% для EAN-13) не работают, можно попробовать уменьшить изображение штрихкода по высоте, но сохранить его полную ширину, что часто помогает сканерам его распознать.

    
    // Макет содержит элемент "Рисунок" с именем "КартинкаШК"
    // В свойстве "Текст" элемента "КартинкаШК" пишем выражение:
    // "глСервис.НарисоватьШтрихкод(Таб.ТекущийОбъект,13,Штрихкод)"
    // где 13 - тип штрихкода, Штрихкод - значение для кодирования
    
  7. Вызов пользовательских исключений

    Для более гибкой обработки ошибок в блоках Попытка-Исключение, 1С++ предлагает метод ВыполняемыйМодуль.СформироватьОшибку(). Это позволяет генерировать пользовательские исключения с заданным текстом, которые затем могут быть перехвачены и обработаны стандартными средствами 1С, например, функцией ОписаниеОшибки().

    
    Попытка
        // ... Ваш код ...
        Если ЧтоТоКриво Тогда
            ВМ = СоздатьОбъект("ВыполняемыйМодуль");
            ВМ.СформироватьОшибку("Обнаружена критическая ошибка: Хрень!");
        КонецЕсли;
        // ... продолжение кода при отсутствии ошибки ...
    Исключение
        ОшибкаТекст = ОписаниеОшибки(); // Здесь будет "Обнаружена критическая ошибка: Хрень!"
        Сообщить("Произошла ошибка: " + ОшибкаТекст);
    КонецПопытки;
    
  8. Предотвращение максимизации окна

    Для контроля за размерами окон FormEx позволяет программно управлять состоянием окна. Чтобы предотвратить максимизацию окна, мы можем использовать свойство Максимизирована объекта РасширениеФормы, устанавливая его значение в 0. Это полезно для окон, которые должны иметь фиксированный размер или ограничиваться определенной областью экрана.

    
    Процедура ПослеОткрытия()
        ФормаРасш = СоздатьОбъект("РасширениеФормы");
        ФормаРасш.УстановитьФорму(Форма); // Привязка к текущей форме
        ФормаРасш.Максимизирована = 0; // Запретить максимизацию
    КонецПроцедуры
    
  9. Хеширование MD5 и SHA-256

    Хотя FormEx напрямую не предоставляет метод для вычисления хеша SHA-256 (в отличие от MD2 и MD5, которые могут использовать внутренние методы 1С), мы можем решить эту задачу с помощью внешних компонент или объектов .NET Framework через COM-интерфейс. В частности, объект System.Security.Cryptography из .NET позволяет вычислять хеши SHA-256, что важно для обеспечения безопасности и взаимодействия с современными системами, требующими сильной криптографии.

Общие советы и инструменты

Эффективная разработка на 1С 7.7, особенно с использованием таких инструментов как FormEx, часто требует применения дополнительных средств и методик.

  1. Использование 1С++ и TurboMD

    Компонента FormEx прекрасно работает в связке с 1С++ (1cpp.dll). Эти две компоненты взаимно дополняют друг друга, предоставляя еще больший контроль над интерфейсом и внутренними механизмами 1С. Для комфортной разработки на 1С 7.7 крайне рекомендуем использовать такие инструменты как OpenConf, Colorer для подсветки синтаксиса, и особенно TurboMD. TurboMD позволяет вносить изменения в конфигурацию без закрытия режима "Предприятие", что значительно ускоряет процесс отладки и разработки, делая его сравнимым по удобству с современными средами.

  2. Стратегии логирования для отладки

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

  3. Управление множеством компонентов и версиями

    При активном использовании внешних компонент, таких как FormEx и 1С++, важно контролировать их версии. Старые версии могут не поддерживать новый функционал или вызывать конфликты. Хотя прямого универсального механизма выгрузки сторонних ВК из 1С 7.7 нет, FormEx сам по себе имеет функции управления, а также может быть использован для проверки наличия и версии других компонент. Размещая специфические версии FormEx в каталоге информационной базы, а не в общем каталоге BIN, мы можем обеспечить работу разных проектов с разными версиями компоненты.

← На главную