Из 321 экспортного метода общего модуля ОбщегоНазначения в типовой УТ для Казахстана 2.2.16.5 при переходе на 3.4.4.87 пропадают 219, а сам модуль остаётся на месте. Внешняя обработка, которая зовёт один из этих методов, после перехода откроется без единой ошибки и упадёт только на строке с вызовом. Заранее об этом не скажет никто: проверка модулей при обновлении внешние обработки не видит вообще, потому что они не часть конфигурации.
Оговорюсь сразу. Переход с 2.2 на 3.4 это смена редакции с переносом данных в новую базу, обычным обновлением его никто не делает. Я взял его намеренно как худший случай: здесь ломается всё, что вообще может сломаться, и хорошо видно, как именно. Механизм молчания при этом тот же, что у любого обновления типовой, хоть через сравнение-объединение, хоть через установку обновления.
В этом сентябре на форуме Инфостарта снова спрашивали, почему после обновления типовой сломались печатные формы. А всё готовое про внешние печатные формы, что я нашёл на площадке, это отладчики: запустить форму и поймать ошибку руками, по одной, когда она уже упала у пользователя. Мне хотелось видеть такие поломки до переноса. Я выгрузил в файлы две типовые поставки, 2.2.16.5 и 3.4.4.87, сверил их программный интерфейс и прогнал по ним настоящую внешнюю обработку обмена с сайтом стороннего разработчика, написанную под УТ на обычных формах 8.2.
Почему конфигуратор молчит
Обновление конфигурации работает с тем, что лежит в конфигурации. Внешняя обработка лежит файлом на диске или строкой справочника "Дополнительные отчёты и обработки" с двоичными данными внутри. Для сравнения-объединения и обновления базы данных это просто данные, как картинка в присоединённом файле.
Пакетная проверка модулей тоже не спасает. У /CheckModules нет ключа для внешних обработок. Если передать ему такой ключ по привычке, платформа молча проигнорирует незнакомый параметр, проверит модули конфигурации базы и ответит "Синтаксических ошибок не обнаружено!". Я поймал это на своей обработке с заведомо битым кодом: Если Тогда без условия и необъявленная переменная получили тот же зелёный ответ на двух базах. Проверка ошибку не пропускала, она на этот файл просто не смотрела.
Остаётся компилятор, который срабатывает, когда обработку открывают. Дальше всё зависит от того, как сломан вызов: поломки бывают трёх видов, и проявляются они в разный момент. Все три я проверил одним фрагментом в тестовой базе УТ 11.5 на платформе 8.3.27. Компиляцию решает платформа, от конфигурации она не зависит, а общие модули ОбщегоНазначения и ОбщегоНазначенияКлиентСервер есть в любой конфигурации на БСП.
// Условие "Если Ложь" нужно, чтобы строка никогда не исполнилась: // смотрим только на компиляцию. // 1. Общего модуля нет: ошибка компиляции, // "Переменная не определена (МодульКоторогоНет)". Выполнить("Если Ложь Тогда Ж = МодульКоторогоНет.Метод(); КонецЕсли;"); // 2. Модуль есть, метода нет: компилируется без замечаний. Выполнить("Если Ложь Тогда ОбщегоНазначения.НетТакого(1); КонецЕсли;"); // 2а. Метод есть, параметров у него пять, передаём восемь: тоже компилируется. Выполнить("Если Ложь Тогда ОбщегоНазначенияКлиентСервер.СообщитьПользователю(1,2,3,4,5,6,7,8); КонецЕсли;"); // 3. Документа нет: тоже компилируется. Выполнить("Если Ложь Тогда Д = Документы.НетТакогоДокумента.СоздатьДокумент(); КонецЕсли;");
Нет общего модуля целиком. Имя модуля для компилятора превращается в необъявленную переменную, и обработка не открывается совсем. Ровно эту ошибку я получил и на своей внешней обработке, когда открыл её в базе с режимом совместимости 8.2, только переменной там была системная НаправлениеПоиска, которой в 8.2 нет. Такую поломку хотя бы видно сразу.
Модуль есть, метода в нём нет. Компилятор это пропускает, лишние параметры у существующего метода тоже. Вызов метода общего модуля платформа разрешает в момент исполнения строки: без условия Если Ложь второй вызов падает с "Метод объекта не обнаружен (НетТакого)", вызов 2а с "Слишком много фактических параметров". Обработка откроется и упадёт на той строке, до которой дошло исполнение. Если строка в ветке, куда заходят раз в месяц, поломку найдут через месяц.
Нет объекта метаданных, например Документы.ЗаказПокупателя. Обращение к менеджеру по имени тоже разрешается при исполнении, ошибка "Поле объекта не обнаружено (НетТакогоДокумента)" приходит на строке.
Две поломки из трёх компилятор не видит в принципе, и узнать о них заранее можно только сверкой вызовов с новым релизом. Живая база тут помогает мало: по её метаданным видно, есть ли общий модуль, но не видно, какие в нём экспортные методы и сколько у них параметров. Для этого нужен текст модулей, то есть выгрузка конфигурации в файлы.
Что теряет программный интерфейс при переходе с 2.2 на 3.4
Между 2.2.16.5 и 3.4.4.87 смена поколения. Редакция 2.2 это обычное приложение в режиме совместимости 8.2, редакция 3.4 управляемая и построена на БСП. Я сравнил экспортные методы всех общих модулей и модулей менеджеров старой редакции с новой. "Без изменений" в таблице значит три вещи сразу: метод в новой редакции есть, он экспортный, и старый вызов подходит к нему по числу параметров.
| Модулей с экспортом | Экспортных методов в 2.2.16.5 | Модуль ушёл целиком (методов) | Метод пропал из оставшегося модуля | Стал неэкспортным | Сузилось число параметров | Без изменений | |
|---|---|---|---|---|---|---|---|
| Общие модули | 120 | 2 839 | 51 (1 214) | 710 | 9 | 55 | 851 (30,0 %) |
| Модули менеджеров | 15 | 109 | 2 (50) | 10 | 1 | 3 | 45 |
| Всего | 135 | 2 948 | 53 (1 264) | 720 | 10 | 58 | 896 (30,4 %) |

Больше всего, 1 214 методов, ушло вместе с модулями: 51 общего модуля в 3.4 просто нет. Ещё 710 методов пропали из модулей, которые по имени остались. Это самый коварный случай, потому что имя модуля в коде выглядит живым. ОбщегоНазначения в 3.4 есть, а из 321 его экспортного метода в 2.2 там нет 219, то есть двух третей.
Неэкспортными стали всего 9 методов общих модулей, число параметров сузилось у 55. Против 1 924 пропавших методов это почти ничего, и на живом коде ниже будет видно, чем это оборачивается.
Одна настоящая обработка: 79 вызовов, 33 не переживут
Типовых внешних печатных форм в поставке 2.2.16.5 нет: ни в самой конфигурации, ни среди её двоичных макетов. Поэтому я проверял то, что реально живёт в базах: обработку обмена с сайтом от стороннего разработчика, написанную под УТ на обычных формах 8.2. В её комплекте ещё три файла, но вызовы типовой почти все в основной обработке: 77 строк из 79 дала она, 2 дал загрузчик.
| Итог по 79 вызовам типовой (46 разных методов и объектов) | Вызовов |
|---|---|
| Сломается при переходе на 3.4.4.87 | 33 |
| объекта метаданных в 3.4 нет | 26 |
| общего модуля в 3.4 нет целиком | 4 |
| модуль есть, метода нет | 3 |
| метод стал неэкспортным | 0 |
| не сходится число параметров | 0 |
| Не работает уже на 2.2.16.5 | 9 |
| В порядке | 37 |
Я ждал, что главной бедой будут сигнатуры: параметр добавили, параметр убрали. Проверка числа параметров заложена в инструмент с самого начала, и на этой обработке она не сработала ни разу. При смене поколения меняется состав конфигурации: документа, справочника или регистра, в который обработка писала, в новой редакции под этим именем больше нет. Из 33 поломок таких 26.
Какие именно вызовы и что в 3.4.4.87 стоит на их месте. Наличие "замены" я проверил по выгрузке 3.4.4.87, переносить сами вызовы на новые имена не стал, и ниже будет видно почему.
| Вызов в обработке (в 2.2.16.5 есть) | В 3.4.4.87 | Что там вместо |
|---|---|---|
ОбщегоНазначения.СообщитьОбОшибке |
нет метода | ОбщегоНазначенияКлиентСервер.СообщитьПользователю |
ЗаполнениеДокументов.ЗаполнитьШапкуДокумента |
нет модуля | модуля ЗаполнениеДокументов нет целиком |
Документы.ЗаказПокупателя.СоздатьДокумент() |
нет объекта | документ ЗаказКлиента |
Справочники.КонтактныеЛицаКонтрагентов.СоздатьЭлемент() |
нет объекта | справочник КонтактныеЛицаПартнеров |
РегистрыСведений.КонтактнаяИнформация.СоздатьНаборЗаписей() |
нет объекта | табличная часть КонтактнаяИнформация у объектов (у Партнеры есть), модуль УправлениеКонтактнойИнформацией |
ПланыВидовХарактеристик.СвойстваОбъектов |
нет объекта | ДополнительныеРеквизитыИСведения |
Если у вас обработка под 2.2 и впереди переход на 3.4, начинайте с этого списка. Каждая замена объекта тянет за собой другие реквизиты и другую логику заполнения.
Замена по имени не равна замене по смыслу
Первая строка таблицы выглядит как механическая правка: было одно имя, стало другое. Я открыл оба метода в выгрузках, и ведут они себя по-разному. В 2.2.16.5 процедура такая (сокращено):
// УТ для Казахстана 2.2.16.5, общий модуль ОбщегоНазначения Процедура СообщитьОбОшибке(ТекстСообщения, Отказ = Ложь, Заголовок = "",Статус = Неопределено) Экспорт // ... Отказ = Истина; #Если ВнешнееСоединение Тогда // ... ВызватьИсключение (ТекстСообщения); #Иначе // ... Сообщить(ТекстСообщения, Статус); #КонецЕсли КонецПроцедуры
Под внешним соединением старая процедура бросает исключение. Для обмена с сайтом, который запускают снаружи, это и есть остановка на ошибке. Новая процедура в 3.4.4.87 такого не делает:
// УТ для Казахстана 3.4.4.87, общий модуль ОбщегоНазначенияКлиентСервер Процедура СообщитьПользователю( Знач ТекстСообщенияПользователю, Знач КлючДанных = Неопределено, Знач Поле = "", Знач ПутьКДанным = "", Отказ = Ложь) Экспорт Сообщение = Новый СообщениеПользователю; Сообщение.Текст = ТекстСообщенияПользователю; // ... Сообщение.Сообщить(); Отказ = Истина; КонецПроцедуры
Замените в обработке одно имя на другое, и код скомпилируется и отработает. Только там, где раньше обмен падал с внятным текстом, теперь он напишет сообщение, которого под внешним соединением никто не увидит, и пойдёт дальше. Второй параметр тоже разошёлся: в старой процедуре вторым шёл Отказ, в новой вторым идёт КлючДанных, а Отказ уехал на пятое место. Если старый код передавал Отказ вторым параметром, после переименования булево уйдёт туда, где ждут ссылку на объект.
С объектами всё ещё строже. ЗаказКлиента занимает место ЗаказПокупателя, но это другой документ с другими реквизитами, а контактная информация из отдельного регистра сведений переехала в табличные части самих объектов. Поэтому инструмент автозамену и не предлагает. Он говорит, какой вызов сломается и почему, а чем его заменить, решает тот, кто знает, что обработка должна делать.
Что не подтвердилось по дороге
Сигнатуры как главный риск. На реальной обработке ноль поломок по числу параметров и ноль по экспорту при 33 поломках всего. Проверку сигнатур я оставил: при обновлении внутри одной редакции картина может быть другой.
Хватит живых метаданных базы. Метаданные говорят, есть ли общий модуль и документ, но про методы внутри модуля не знают ничего. Без выгрузки в файлы вызов метода получает статус "не проверено", и в отчёте так и написано.
Методы коллекций. Первая версия видела в ПланыОбмена.ВыбратьИзменения(...) и Документы.ТипВсеСсылки() объект с именем ВыбратьИзменения и писала "нет объекта". На обработках под 2.2 это дало 13 ложных строк: 92 вызова до правки, 79 после. Правило простое: объект метаданных скобками не вызывается, значит Коллекция.Имя( это метод самой коллекции.
Проверка прямо в старой базе. В базе 2.2.16.5 обработка не компилируется: режим совместимости 8.2 прячет всё, что появилось в 8.3. Обход проверен прогоном: запускать в любой современной базе и давать обе выгрузки.
Обработка, написанная шире одной конфигурации
9 вызовов той же обработки не работают уже на 2.2.16.5, до всякого перехода. Четыре из них Перечисления.СтавкиНДС: в УТ для Казахстана 2.2 такого перечисления нет, обработка писалась и под российскую УТ. Ещё пять это объекты её собственного комплекта, которых в типовой нет и не было. Проверка ставит им отдельный статус "уже сломано": к переходу они отношения не имеют, в этой базе такая ветка кода просто никогда не работала.
В обратную сторону тоже есть на что посмотреть. Я прогнал по тем же двум поставкам 42 свои обработки, написанные под БСП. Они почти самодостаточны: вызовов типовой на все 42 набралось 14. На 2.2.16.5 не работали бы 13 из них, и 7 это модули ДополнительныеОтчетыИОбработки*, то есть функция регистрации дополнительной обработки, которой в 2.2 нет. Даже простая дополнительная обработка под БСП привязана к конфигурации ещё до первой строки своей логики.
Как проверить свои обработки до обновления
Я собрал это в бесплатную обработку "Проверка внешних обработок при обновлении типовой". Она берёт внешние обработки и печатные формы из справочника дополнительных отчётов и обработок или из папки с файлами .epf и .erf и распаковывает их без конфигуратора. Дальше находит вызовы общих модулей и менеджеров типовой и сверяет каждый с текущей конфигурацией и с выгрузкой нового релиза. У каждого вызова свой статус (СЛОМАЕТСЯ, УЖЕ СЛОМАНО, НЕ ПРОВЕРЕНО, ОК), номер строки и причина. Четыре файла комплекта обработки обмена сверялись 1,7 секунды, с подключением к базе около 11 секунд.
Порядок такой.
- Выгрузка текущей конфигурации. Кнопка "Выгрузить нужные модули текущей конфигурации" сама запустит конфигуратор в пакетном режиме и выгрузит только те объекты, которые реально вызываются. Полная выгрузка конфигурации в файлы тоже подойдёт, если она у вас уже есть.
- Выгрузка нового релиза. Главное правило: делать её из копии своей базы после сравнения-объединения. В чистом шаблоне поставки нет ваших доработок. Если обработка зовёт доработанный объект, по шаблону она получит СЛОМАЕТСЯ, хотя при нормальном обновлении доработка переедет и вызов останется рабочим. Копия после объединения показывает ровно ту конфигурацию, которая будет у вас после обновления.
- Проверить и начать с красных строк: СЛОМАЕТСЯ стоит сверху, у каждой строки видно, в какой обработке вызов и что с ним в новом релизе.
Если текущая база в режиме совместимости 8.2, как у УТ 2.2, запускайте обработку в любой современной базе и давайте обе выгрузки файлами: сама старая база её не скомпилирует.
Где проверка заканчивается
Проверка статическая: код обработок она читает, но не исполняет. Отсюда границы.
- Вызовы через строку не видны.
Выполнить(...),ОбщегоНазначения.ОбщийМодуль("Имя")и всё, что собирается текстом во время работы, статикой не разобрать. - Методы объектов не проверяются. Сверяются вызовы общих модулей и менеджеров (
Документы.Имя.Метод()). Вызов метода уДокументОбъект, полученного в переменную, в сверку не попадает. - Смысл не проверяется. Случай с
СообщитьОбОшибкеинструмент покажет как "нет метода". Что у замены другое поведение под внешним соединением, видно только глазами в коде обеих редакций. - Объекты расширений получают НЕ ПРОВЕРЕНО. В выгрузке типового релиза их нет и быть не должно, и выдавать их за поломку было бы враньём.
- Реквизит формы с именем общего модуля пока не отличается от модуля. Локальные переменные и параметры отличаются.
- Проверено на платформе 8.3.27, на поставках УТ для Казахстана 2.2.16.5 и 3.4.4.87, серверные базы. Конфигурации без БСП, файловые базы, веб-клиент и Linux-сервер не гонялись.
Переход с 2.2 на 3.4 это худший случай. Сколько ломается при обновлении внутри одной редакции, между соседними релизами типовой, я не мерил, поэтому цифры здесь не будет. Проверка там та же.
Другие наши инструменты
- Помощник перехода на 1С 8.5 - если вместе с конфигурацией собираетесь обновлять и платформу: что поменялось в самой 8.5 и что это задевает в вашем коде.
- Анализ кода внешних обработок - когда внешние обработки надо проверить на качество кода: запросы в цикле, запись без проверок, обращения наружу.
- Чек-ап СУБД под 1С - перед обновлением большой базы стоит убедиться, что сервер СУБД настроен под 1С.
- Карта объёмов базы 1С - чтобы до обновления понять, какие таблицы в базе самые большие и что растёт.
- Выгрузка метаданных для LLM - если разбирать разницу между релизами удобнее с нейросетью: структура конфигурации файлом, без подключения к базе.
Вопрос
Как вы сейчас узнаёте, что внешняя печатная форма или обработка сломается после обновления: гоняете на копии или ждёте звонка от пользователя? Если прогоните проверку на своих обработках перед ближайшим обновлением, напишите в комментариях, чего вышло больше: пропавших объектов или пропавших методов общих модулей.
Вступайте в нашу телеграмм-группу Инфостарт