Почему 1С 7.7 падает в AppCrash при открытии документов из табличной формы Moxel с использованием FormEx-меню и вложенных списков с иконками?

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

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

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

Детализация проблемы: Когда и где возникает AppCrash?

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

Мы обратим внимание на следующие ключевые особенности проявления ошибки:

  1. Контекст вызова: Если этот же всплывающий список вызывается из журнала документов или из видимой ТаблицаЗначений на обычной форме, все работает корректно, и документ открывается без проблем. Однако, если список вызывается из отчета или древовидной структуры, представленной в Moxel, возникает AppCrash. Это указывает на специфику взаимодействия FormEx с табличным документом Moxel.
  2. Роль FormEx: Если в дереве Moxel мы отключаем вызов FormEx-списка и используем типовой метод обработки ячейки 1С, документ открывается нормально. Это подтверждает, что причиной сбоя является именно FormEx или его взаимодействие с окружением.
  3. Влияние иконок: Один из важнейших моментов, выявленных в ходе обсуждения, заключается в том, что если список создается без использования пиктограмм (иконок), то AppCrash не происходит. Это говорит о том, что визуальные элементы, а именно иконки, являются триггером проблемы.
  4. Вложенность меню: Проблема усугубляется и становится стабильно воспроизводимой при наличии нескольких вложенных меню, которые также содержат иконки. При этом, если отключить или закомментировать любое из этих трех вложенных меню, проблема исчезает. Это свидетельствует о том, что не конкретная иконка или список вызывают сбой, а общая сложность или объем графических данных, обрабатываемых одновременно, возможно, приводят к переполнению буфера или ошибке в компоненте FormEx.
  5. Версии компонент: В нашей ситуации используются FormEx версии 2.0.5.107 и 1С++ версии 3.2.4.1. Важно всегда проверять актуальность и совместимость версий внешних компонент.
  6. Внешние факторы: Отмечено, что проблема совпала по времени с изменениями прав доступа к папкам. Хотя права на необходимые каталоги (1с/Bin, папки с базами) были проверены и открыты, такие изменения могут косвенно влиять на стабильность работы приложений.

Анализируем код вызова меню и открытия формы

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

Стандартный подход к созданию меню и открытию формы выглядит следующим образом:


Процедура ОбработкаЯчейкиТаблицы(Расшифровка,ФСО,Таб,Адрес)
    // Отключаем стандартную обработку формы для Moxel
    ФСО = 0; 
    
    // Инициализация переменной для выбора
    Выб = 0; 
    
    // Создаем объект СписокЗначений для нашего меню
    Меню = СоздатьОбъект("СписокЗначений");
    
    // Загружаем картинку (ряд иконок) для меню
    Картинка = СоздатьОбъект("Картинка");
    Картинка.Загрузить(КаталогИБ() + "ExtForms\картинки\МойПолныйРядИконок.bmp");
    
    // Добавляем пункты в основное меню
    Меню.ДобавитьЗначение("док0","Открыть");
    // ****************тут добавляются другие элементы списка,
    // включая вложенные списки с собственными иконками.
    
    // Создаем объект "Сервис" для вызова FormEx-функций
    Сервис = СоздатьОбъект("Сервис");
    
    // Вызываем FormEx-метод для отображения меню и выбора значения
    Если Сервис.ВыбратьЗначение(Меню,Выб,"",0,2,Картинка)<>0 Тогда 
        // Если что-то выбрано, открываем форму документа
        ОткрытьФорму(Расшифровка);
        Возврат;
    КонецЕсли;
    
КонецПроцедуры

Разберем ключевые элементы этого кода:

  1. ФСО = 0;: Это критически важная строка. Установка ФСО в 0 (Флаг Стандартной Обработки) отключает стандартное поведение 1С по обработке ячейки, что позволяет компоненте FormEx полностью взять управление на себя. Если этот параметр не установить, могут возникать конфликты между стандартной и внешней обработкой.
  2. СписокЗначений: Этот объект используется для построения структуры меню. Он позволяет создавать как простые пункты, так и сложные вложенные списки.
  3. Картинка: Объект Картинка загружает изображение, которое затем используется FormEx для отрисовки иконок рядом с пунктами меню. В нашем случае используется один файл МойПолныйРядИконок.bmp, содержащий несколько иконок, которые FormEx динамически вырезает и отображает. Размеры такой картинки составляют 592x16 пикселей.
  4. Сервис.ВыбратьЗначение(): Это функция компоненты FormEx, которая отображает всплывающее меню. Она принимает в качестве параметров сам объект меню (СписокЗначений), переменную для выбранного значения, заголовок, а также объект Картинка и другие параметры для кастомизации внешнего вида.
  5. ОткрытьФорму(Расшифровка): После выбора пункта меню, если выбор состоялся, мы пытаемся открыть форму документа. Переменная Расшифровка в данном контексте представляет собой ссылку на объект базы данных (документ), который был получен из ячейки Moxel.

Проблема, судя по всему, заключается не в логике открытия формы (ОткрытьФорму), а в этапе отрисовки и взаимодействия FormEx с графическими ресурсами и операционной системой в специфическом контексте Moxel.

Предполагаемые причины AppCrash

Рассмотрим несколько гипотез, почему 1С 7.7 может падать в AppCrash в описанной ситуации:

1. Конфликт версий компонент или двойная загрузка библиотек

Одной из наиболее частых причин AppCrash в 1С 7.7, особенно при использовании внешних компонент, является конфликт между разными версиями или даже двойная загрузка одной и той же библиотеки. FormEx и 1С++ (1CPP.dll) являются мощными, но сложными компонентами, которые глубоко интегрируются в ядро 1С.

2. Проблемы с отрисовкой графики FormEx в Moxel

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

3. Ошибки в самой компоненте FormEx (старые версии)

FormEx, как любая сторонняя компонента, может содержать свои собственные баги, особенно в старых версиях. Разработчики FormEx постоянно работают над их устранением. Известны случаи, когда ошибки в FormEx приводили к AppCrash:

4. Недостаток системных ресурсов или памяти

Платформа 1С 7.7, будучи 32-битным приложением, имеет ограничения по использованию оперативной памяти. Создание и отрисовка сложных графических элементов, особенно при наличии нескольких вложенных меню и большого количества иконок, могут быстро исчерпать доступные ресурсы, что приводит к ошибкам выделения памяти и, как следствие, AppCrash.

Процесс поиска решения и отладки

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

Шаг 1: Изолирование проблемы с иконками

  1. Тестирование без иконок: Мы выясняем, что если создать FormEx-меню без использования объекта Картинка и не указывать пиктограммы для пунктов меню, то система работает стабильно. Это не решение, но важный диагностический признак, который указывает на связь проблемы с графическими ресурсами и FormEx.

Шаг 2: Анализ вложенных меню

  1. Последовательное отключение: Мы обнаруживаем, что проблема AppCrash возникает только тогда, когда активны все три вложенных меню с иконками. Если любое из этих вложенных меню отключить или закомментировать в коде, система перестает падать. Это указывает на кумулятивный эффект или на то, что FormEx не справляется с определенной сложностью или количеством одновременно отображаемых графических элементов.

Шаг 3: Эксперименты с параметрами FormEx и картинками

В ходе отладки мы можем попробовать различные варианты, чтобы проверить их влияние на стабильность системы:

  1. Добавление ФСО = 0;: Мы убедимся, что стандартная обработка ячейки отключена, чтобы избежать конфликтов.
  2. Использование ПараметрыЦвета: В FormEx можно передавать параметры цвета для кастомизации меню. Иногда явное указание этих параметров может повлиять на стабильность, хотя это скорее обходной путь, чем прямое решение проблемы AppCrash. Пример из обсуждения:
    
    ПараметрыЦвета = СоздатьОбъект("СписокЗначений");
    ПараметрыЦвета.Установить("ЦветФонаВыделения",255); // Например, красный фон
    ПараметрыЦвета.Установить("ЦветРамкиВыделения",0); // Черная рамка
    
  3. Изменение источника картинок: Мы можем попробовать загружать картинки не из файла, а из библиотеки картинок 1С. Это меняет способ доступа к графическому ресурсу и может влиять на работу компоненты.
    
    // Старый метод:
    // Картинка = СоздатьОбъект("Картинка");
    // Картинка.Загрузить(КаталогИБ() + "ExtForms\картинки\МойПолныйРядИконок.bmp");
            
    // Новый метод (из библиотеки картинок):
    Картинка = СоздатьОбъект("Картинка");
    Картинка.Загрузить("МойПолныйРядИконок");
    
  4. Изменение размеров картинок: Хотя это может показаться незначительным, иногда определенные размеры изображений могут вызывать проблемы в компонентах. Например, мы можем попробовать изменить высоту ряда иконок с 16 пикселей на 15.
  5. Тестирование с примером кода: Для проверки общей работоспособности FormEx с вложенными списками и иконками, мы можем использовать упрощенный тестовый код:
    
    // Пример рабочего кода из обсуждения для тестирования FormEx-меню
    Процедура ПриОткрытии()
        Таб = СоздатьОбъект("Таблица");
        Таб.ИсходнаяТаблица("Таблица");
        Таб.Вывести();
        Таб.ТолькоПросмотр(1);
        Таб.Показать();
    КонецПроцедуры
            
    Процедура ОбработкаЯчейкиТаблицы(Расшифровка,ФСО,Таб,Адрес)
        Фсо=0;
        Сервис = СоздатьОбъект("Сервис");
        Список = СоздатьОбъект("СписокЗначений");
        Список.ДобавитьЗначение(1,"[icon:1]Пункт 1");
        Список.ДобавитьЗначение(2,"[icon:2]Пункт 2");
        Список.ДобавитьЗначение(3,"[icon:3]Пункт 3");
        Список.ДобавитьЗначение(4,"[icon:4]Пункт 4");
        Список.ДобавитьЗначение(0,"-");
        // создаем вложенный список
        СписокДоп = СоздатьОбъект("СписокЗначений");
        СписокДоп.ДобавитьЗначение(551,"Пункт 51");
        СписокДоп.ДобавитьЗначение(552,"Пункт 52");
        СписокДоп.ДобавитьЗначение(553,"Пункт 53");
        СписокДоп.ДобавитьЗначение(554,"Пункт 54");
        // добавляем вложенный список
        Список.ДобавитьЗначение(СписокДоп,"Пункт 5");
        Список.ДобавитьЗначение(6,"Пункт 6");
        Список.ДобавитьЗначение(7,"Пункт 7");
        Картинка = СоздатьОбъект("Картинка");
        // Предполагается, что файл 1.bmp находится в ExtForms
        Картинка.Загрузить(КаталогИБ() + "ExtForms\1.bmp"); 
        ПараметрыЦвета = СоздатьОбъект("СписокЗначений");
        ПараметрыЦвета.Установить("ЦветФонаВыделения",255);
        ПараметрыЦвета.Установить("ЦветРамкиВыделения",0);
        Выб = "";
        Если Сервис.ВыбратьЗначение(Список,Выб,"Тестовый выбор значения",0,0,Картинка,ПараметрыЦвета) = 1 Тогда
            Сообщить(Выб);
        КонецЕсли;
    КонецПроцедуры 
    

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

Обходное решение, найденное автором

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

  1. Изменение типа одного из вложенных меню: Вместо того чтобы иметь три постоянно развернутых (или активных при наведении) вложенных меню с иконками, одно из них было изменено на активацию "по нажатию". То есть, оно перестало быть непосредственно вложенным списком, а стало пунктом, который требует отдельного клика для раскрытия.

Почему это сработало?

Мы предполагаем, что замена одного из вложенных меню на "по нажатию" снизила общую сложность структуры, которую FormEx пытается отрисовать или управлять ею в Moxel. Это могло привести к следующим эффектам:

Это решение является компромиссным, но очень практичным. Оно позволило сохранить основную функциональность FormEx и использование иконок, при этом устранив AppCrash.

Рекомендации по предотвращению подобных проблем

Чтобы минимизировать риск возникновения AppCrash при работе с FormEx и другими внешними компонентами в 1С 7.7, мы рекомендуем следовать следующим правилам:

  1. Актуализация версий компонент: Мы должны использовать самые стабильные и актуальные версии FormEx и 1С++, доступные для 1С 7.7. Регулярно проверяйте форумы и ресурсы разработчиков (например, 1cpp.ru) на предмет обновлений и исправлений.
  2. Проверка совместимости: Убедитесь, что все используемые внешние компоненты совместимы друг с другом и с версией вашей платформы 1С 7.7. Обратите внимание на порядок их загрузки.
  3. Оптимизация изображений:
    • Размер: Используйте иконки минимально необходимого размера.
    • Формат и битность: Проверяйте рекомендованные форматы (часто это 24-битные BMP) и битность изображений для FormEx.
    • Количество: Если возможно, уменьшайте количество иконок, используемых в одном меню, или распределяйте их по разным меню.
  4. Тщательная проверка структуры меню: Мы должны избегать чрезмерно глубокой вложенности меню, особенно при использовании графических элементов. Если глубокая вложенность необходима, рассмотрите возможность активации некоторых уровней меню по явному клику, а не по наведению курсора.
  5. Явное управление параметрами FormEx: Всегда устанавливайте ФСО = 0; в ОбработкаЯчейкиТаблицы при использовании FormEx для перехвата событий. Мы также можем экспериментировать с явным указанием ПараметрыЦвета, даже если они не влияют напрямую на решение, они могут косвенно влиять на отрисовку.
  6. Мониторинг системных ресурсов: Во время тестирования мы наблюдаем за использованием оперативной памяти и ресурсов процессора. Если наблюдается резкий рост потребления памяти перед AppCrash, это может указывать на утечки памяти или неэффективное использование ресурсов компонентой.
  7. Последовательная отладка: При возникновении AppCrash мы отключаем или упрощаем функционал шаг за шагом:
    • Отключаем иконки.
    • Убираем вложенные меню.
    • Отключаем внешние компоненты по очереди.
    Такой подход позволяет точно локализовать источник проблемы.
  8. Тестирование в разных средах: Мы проводим тестирование как на локальных машинах, так и в терминальном режиме, если таковой используется, поскольку особенности графического рендеринга в этих средах могут отличаться.

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

← На главную