Мы сталкиваемся с распространенной, но порой труднодиагностируемой проблемой: приложение 1С 7.7 внезапно завершает работу с ошибкой AppCrash при выполнении, казалось бы, обычной операции – открытии документа. Давайте подробно разберем ситуацию, которая возникает при использовании внешних компонент FormEx и 1С++ для расширения функционала табличных документов Moxel, особенно когда мы работаем с интерактивными меню, содержащими иконки и вложенные списки.
Эта проблема может проявляться как нестабильное поведение системы, которое сложно воспроизвести, однако тщательный анализ помогает выявить корни AppCrash и найти эффективные обходные пути или решения. Мы вместе рассмотрим типичные сценарии возникновения такой ошибки, проанализируем код и предложенные варианты решения.
В начале обсуждения мы видим, что система 1С 7.7 падает с ошибкой AppCrash, когда пользователи пытаются открыть любой документ из печатной формы, которая отображается в табличном редакторе Moxel. Это происходит при использовании специальной обработки ячейки, которая вызывает всплывающий список, созданный с помощью компоненты FormEx.
Мы обратим внимание на следующие ключевые особенности проявления ошибки:
ТаблицаЗначений на обычной форме, все работает корректно, и документ открывается без проблем. Однако, если список вызывается из отчета или древовидной структуры, представленной в Moxel, возникает AppCrash. Это указывает на специфику взаимодействия FormEx с табличным документом Moxel.1с/Bin, папки с базами) были проверены и открыты, такие изменения могут косвенно влиять на стабильность работы приложений.Для лучшего понимания ситуации, давайте рассмотрим типовой фрагмент кода, который используется для создания всплывающего меню с помощью FormEx и последующего открытия документа. Этот код обычно находится в процедуре ОбработкаЯчейкиТаблицы табличного документа.
Стандартный подход к созданию меню и открытию формы выглядит следующим образом:
Процедура ОбработкаЯчейкиТаблицы(Расшифровка,ФСО,Таб,Адрес)
// Отключаем стандартную обработку формы для Moxel
ФСО = 0;
// Инициализация переменной для выбора
Выб = 0;
// Создаем объект СписокЗначений для нашего меню
Меню = СоздатьОбъект("СписокЗначений");
// Загружаем картинку (ряд иконок) для меню
Картинка = СоздатьОбъект("Картинка");
Картинка.Загрузить(КаталогИБ() + "ExtForms\картинки\МойПолныйРядИконок.bmp");
// Добавляем пункты в основное меню
Меню.ДобавитьЗначение("док0","Открыть");
// ****************тут добавляются другие элементы списка,
// включая вложенные списки с собственными иконками.
// Создаем объект "Сервис" для вызова FormEx-функций
Сервис = СоздатьОбъект("Сервис");
// Вызываем FormEx-метод для отображения меню и выбора значения
Если Сервис.ВыбратьЗначение(Меню,Выб,"",0,2,Картинка)<>0 Тогда
// Если что-то выбрано, открываем форму документа
ОткрытьФорму(Расшифровка);
Возврат;
КонецЕсли;
КонецПроцедуры
Разберем ключевые элементы этого кода:
ФСО = 0;: Это критически важная строка. Установка ФСО в 0 (Флаг Стандартной Обработки) отключает стандартное поведение 1С по обработке ячейки, что позволяет компоненте FormEx полностью взять управление на себя. Если этот параметр не установить, могут возникать конфликты между стандартной и внешней обработкой.СписокЗначений: Этот объект используется для построения структуры меню. Он позволяет создавать как простые пункты, так и сложные вложенные списки.Картинка: Объект Картинка загружает изображение, которое затем используется FormEx для отрисовки иконок рядом с пунктами меню. В нашем случае используется один файл МойПолныйРядИконок.bmp, содержащий несколько иконок, которые FormEx динамически вырезает и отображает. Размеры такой картинки составляют 592x16 пикселей.Сервис.ВыбратьЗначение(): Это функция компоненты FormEx, которая отображает всплывающее меню. Она принимает в качестве параметров сам объект меню (СписокЗначений), переменную для выбранного значения, заголовок, а также объект Картинка и другие параметры для кастомизации внешнего вида.ОткрытьФорму(Расшифровка): После выбора пункта меню, если выбор состоялся, мы пытаемся открыть форму документа. Переменная Расшифровка в данном контексте представляет собой ссылку на объект базы данных (документ), который был получен из ячейки Moxel.Проблема, судя по всему, заключается не в логике открытия формы (ОткрытьФорму), а в этапе отрисовки и взаимодействия FormEx с графическими ресурсами и операционной системой в специфическом контексте Moxel.
Рассмотрим несколько гипотез, почему 1С 7.7 может падать в AppCrash в описанной ситуации:
Одной из наиболее частых причин AppCrash в 1С 7.7, особенно при использовании внешних компонент, является конфликт между разными версиями или даже двойная загрузка одной и той же библиотеки. FormEx и 1С++ (1CPP.dll) являются мощными, но сложными компонентами, которые глубоко интегрируются в ядро 1С.
1CPP.dll: Мы должны убедиться, что библиотека 1CPP.dll загружается только один раз. Хотя автор проверил, что упоминание 1cpp.dll в базе и в каталоге ExtForms происходит только один раз в процедуре ПриНачалеРаботыСистемы, это не исключает других сценариев загрузки (например, если она прописана в разных местах системного реестра или в V7PLUS.DLL). Конфликт может возникнуть, если одна версия 1CPP.dll уже загружена, а FormEx пытается использовать свои встроенные или другую версию 1С++, или если FormEx сам содержит встроенные функции 1С++ и при этом подгружается отдельная 1CPP.dll.1CPP.dll обычно должна загружаться первой, так как другие компоненты могут зависеть от ее функционала.Moxel (табличный документ) в 1С 7.7 имеет свою специфику обработки графики, которая отличается от обычных форм. FormEx, при всей своей гибкости, может сталкиваться с трудностями при отрисовке сложных элементов, таких как всплывающие меню с иконками, в этой среде.
FormEx, как любая сторонняя компонента, может содержать свои собственные баги, особенно в старых версиях. Разработчики FormEx постоянно работают над их устранением. Известны случаи, когда ошибки в FormEx приводили к AppCrash:
ОбработкаЯчейкиТаблицы. Если в компоненте есть ошибка в логике перехвата или передачи событий (например, когда событие вызывается как в форме, так и в глобальном модуле одновременно), это может привести к нестабильной работе и сбоям.Платформа 1С 7.7, будучи 32-битным приложением, имеет ограничения по использованию оперативной памяти. Создание и отрисовка сложных графических элементов, особенно при наличии нескольких вложенных меню и большого количества иконок, могут быстро исчерпать доступные ресурсы, что приводит к ошибкам выделения памяти и, как следствие, AppCrash.
Для эффективного решения подобных проблем мы рекомендуем действовать последовательно, используя методы исключения и тестирования. Именно такой подход применил автор темы.
Картинка и не указывать пиктограммы для пунктов меню, то система работает стабильно. Это не решение, но важный диагностический признак, который указывает на связь проблемы с графическими ресурсами и FormEx.В ходе отладки мы можем попробовать различные варианты, чтобы проверить их влияние на стабильность системы:
ФСО = 0;: Мы убедимся, что стандартная обработка ячейки отключена, чтобы избежать конфликтов.ПараметрыЦвета: В FormEx можно передавать параметры цвета для кастомизации меню. Иногда явное указание этих параметров может повлиять на стабильность, хотя это скорее обходной путь, чем прямое решение проблемы AppCrash. Пример из обсуждения:
ПараметрыЦвета = СоздатьОбъект("СписокЗначений");
ПараметрыЦвета.Установить("ЦветФонаВыделения",255); // Например, красный фон
ПараметрыЦвета.Установить("ЦветРамкиВыделения",0); // Черная рамка
// Старый метод:
// Картинка = СоздатьОбъект("Картинка");
// Картинка.Загрузить(КаталогИБ() + "ExtForms\картинки\МойПолныйРядИконок.bmp");
// Новый метод (из библиотеки картинок):
Картинка = СоздатьОбъект("Картинка");
Картинка.Загрузить("МойПолныйРядИконок");
// Пример рабочего кода из обсуждения для тестирования 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 и иконок. Суть решения заключалась в следующем:
Почему это сработало?
Мы предполагаем, что замена одного из вложенных меню на "по нажатию" снизила общую сложность структуры, которую FormEx пытается отрисовать или управлять ею в Moxel. Это могло привести к следующим эффектам:
Это решение является компромиссным, но очень практичным. Оно позволило сохранить основную функциональность FormEx и использование иконок, при этом устранив AppCrash.
Чтобы минимизировать риск возникновения AppCrash при работе с FormEx и другими внешними компонентами в 1С 7.7, мы рекомендуем следовать следующим правилам:
ФСО = 0; в ОбработкаЯчейкиТаблицы при использовании FormEx для перехвата событий. Мы также можем экспериментировать с явным указанием ПараметрыЦвета, даже если они не влияют напрямую на решение, они могут косвенно влиять на отрисовку.Работая с 1С 7.7 и её внешними компонентами, мы всегда помним, что стабильность системы зависит от множества факторов. Вдумчивый подход к разработке и отладке, а также понимание взаимодействия между различными частями системы, помогут нам создавать надежные и эффективные решения.