В практике разработки на платформе 1С часто встречается коварная ситуация: внешняя обработка или программный код заполнения табличных частей (ОЗТЧ) идеально функционирует в файловой базе (например, на копии разработчика), но при переносе в рабочую SQL-среду данные в документе перестают обновляться. Особенно остро эта проблема проявляется в конфигурациях на обычных формах, таких как УПП 1.3, и при использовании СУБД PostgreSQL. Проанализируем причины этого явления и найдем способы решения.
Рассмотрим подробнее, почему поведение системы меняется. В файловой базе данных клиентское приложение (обычно это Толстый клиент) напрямую работает с файлом базы. Объект документа в оперативной памяти и данные в базе синхронизируются практически мгновенно в рамках одного процесса. В клиент-серверном варианте (SQL) между кодом и базой появляется посредник — Сервер приложений 1С.
Когда вы запускаете обработку заполнения, код может выполняться в разных контекстах. Если изменения вносятся в Объект документа, который передан в обработку, в SQL-базе эти изменения часто остаются в «памяти сервера», и форма на клиенте просто «не видит» их, пока данные не будут принудительно перечитаны или объект не будет зафиксирован в базе данных.
Выясним одну из самых частых скрытых причин. Файловая база всегда запускается в режиме Толстого клиента. SQL-база по умолчанию в некоторых настройках может пытаться использовать Тонкий клиент или режим эмуляции обычных форм. В режиме Тонкого клиента работа с объектами типа ДокументОбъект происходит иначе: передача данных между клиентом и сервером идет через сериализацию, и изменения в табличной части могут просто потеряться при возврате управления в форму.
Рекомендация: Убедитесь, что в настройках информационной базы в списке баз или в параметрах запуска принудительно установлен Тип запуска — Толстый клиент. Это критически важно для корректной работы обычных форм в УПП.
Проанализируем техническую связку. Если база работает под управлением PostgreSQL (особенно на платформе версии 8.3.10.2667), могут возникать проблемы с кэшированием объектов. В этой версии платформы были зафиксированы ошибки, когда изменения в табличных частях «откатывались», если транзакция не была завершена явным образом. Кроме того, Postgres чувствителен к операциям с временными таблицами в сложных запросах, которые часто используются в процедурах автозаполнения.
Разберем по шагам, как модифицировать код, чтобы он работал стабильно в любой среде. Основное правило для SQL-версии: Записать объект на сервере и перечитать его на клиенте.
ЗаписиОСтаже или любую другую, необходимо вызвать метод Объект.Записать(). Это гарантирует, что данные физически попали в таблицы SQL-сервера.ДокументОбъект.ЭтаФорма.Прочитать() или Обновить(), чтобы данные из базы подтянулись в интерфейс пользователя.Посмотрим на пример кода, который обрабатывает сложные периоды стажа (как в документе СЗВ-СТАЖ) и учитывает работу в SQL-базе. Обратите внимание на работу с периодами и удаление пустых строк, что часто требуется в таких задачах:
Процедура Автозаполнение_С_Записью(Объект) Экспорт
// ... блок формирования запроса (через МенеджерВременныхТаблиц) ...
Результат = Запрос.Выполнить().Выгрузить();
Если Результат.Количество() = 0 Тогда
Возврат;
КонецЕсли;
// Очищаем старые записи
Объект.ЗаписиОСтаже.Очистить();
Для Каждого Стр Из Результат Цикл
НоваяСтрока = Объект.ЗаписиОСтаже.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, Стр);
// В SQL важно проверять пустые даты перед записью
Если Не ЗначениеЗаполнено(НоваяСтрока.ДатаНачалаПериода) Тогда
НоваяСтрока.ДатаНачалаПериода = Объект.ОтчетныйПериод;
КонецЕсли;
КонецЦикла;
// Критически важный блок для SQL-базы
Попытка
Объект.Записать(РежимЗаписиДокумента.Запись);
Сообщить("Данные успешно сохранены в базе SQL");
Исключение
Сообщить("Ошибка при записи объекта: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Рассмотрим ситуацию с использованием МенеджерВременныхТаблиц, как в исходном коде темы. В SQL-базах время жизни временных таблиц ограничено сеансом и контекстом. Если ваш запрос разбит на несколько этапов, убедитесь, что все они выполняются в рамках одного вызова сервера. В файловой базе менеджер временных таблиц ведет себя более «снисходительно» к разрывам контекста, но в SQL попытка обратиться к таблице, созданной в другом серверном вызове, приведет к ошибке «Таблица не найдена».
Проанализируем фрагмент запроса из темы, где используется замена текста для дополнительных условий:
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "И &ПервоеДополнительноеУсловие",
СтрЗаменить(ПроцедурыПерсонифицированногоУчетаПереопределяемый.СЗВ4_ПолучитьДополнительныеУсловияДляСотрудников,
"Сотрудник.", "Сотрудники."));
Запрос.Текст = ТекстЗапроса;
Такие динамические замены текста запроса должны выполняться крайне аккуратно. В SQL-версии Postgres планы запросов кэшируются, и если структура запроса меняется слишком часто или некорректно, это может приводить к деградации производительности или пустым выборкам при определенных условиях.
Если вы убедились, что код корректен, тип клиента — Толстый, и метод Записать() вызывается, но таблица всё равно пуста — выясним причину в кэше метаданных. SQL-версия 1С активно кэширует структуру таблиц. При обновлении конфигурации или изменении обработки кэш на сервере приложений может «залипнуть».
Попробуйте следующие действия:
%AppData%\1C\1Cv8).Подводя итог, можно сказать: проблема «файловая работает, SQL — нет» в 90% случаев решается принудительным использованием Толстого клиента и добавлением явного вызова Объект.Записать() в коде обработки заполнения.