Каждый разработчик 1С рано или поздно сталкивается с удивительной ситуацией: один и тот же программный код или запрос прекрасно функционирует на одной информационной базе (например, тестовой или демо-базе), но наотрез отказывается работать или даже открываться в конструкторе на другой базе (например, рабочей). При этом конфигурации баз визуально идентичны, а структуры данных кажутся абсолютно одинаковыми.
В этой статье мы подробно разберем именно такой случай, когда при попытке открыть вполне стандартный запрос по виртуальным таблицам остатков регистра бухгалтерии в конструкторе запросов система выдает ошибку. Мы выясним глубинную техническую причину этой проблемы, проанализируем, почему стандартное тестирование и исправление базы данных (ТиИ) оказывается неэффективным, и рассмотрим пошаговые практические методы исправления ситуации.
Рассмотрим ситуацию, с которой столкнулся разработчик. На платформе 1С:Предприятие 8.3 используются две конфигурации со схожими механизмами учета взаиморасчетов: «БИТ Финанс» и «1С:Учет в управляющих компаниях ЖКХ, ТСЖ и ЖСК». В обеих базах присутствует общий модуль УчетВзаиморасчетов с функцией ТекстЗапросаОстаткиАвансов.
Текст запроса, который вызывает сбой конструктора в одной из баз, выглядит следующим образом:
ВЫБРАТЬ
Остатки.Счет КАК Счет,
Остатки.Валюта КАК Валюта,
Остатки.Субконто1 КАК Субконто1,
Остатки.Субконто2 КАК Субконто2,
Остатки.Субконто3 КАК Субконто3,
ЕСТЬNULL(Остатки.Подразделение, &ПустоеПодразделение) КАК Подразделение,
ВЫБОР
КОГДА Остатки.Счет.Валютный
ТОГДА Остатки.ВалютнаяСуммаОстаток * &Множитель
ИНАЧЕ Остатки.СуммаОстаток * &Множитель
КОНЕЦ КАК СуммаВзаиморасчетов,
Остатки.СуммаОстаток * &Множитель КАК СуммаБУ,
Остатки.СуммаНУОстаток * &Множитель КАК СуммаНУ
ПОМЕСТИТЬ ОстаткиАвансов
ИЗ
РегистрБухгалтерии.Хозрасчетный.Остатки(
&МоментВремениОстатков,
Счет В (&СчетаАвансов),
&ВидыСубконтоРасчетов,
Организация = &Организация
И Субконто1 В (&МассивКонтрагенты)
И Субконто2 В (&МассивДоговоры)) КАК Остатки
ГДЕ
ВЫБОР
КОГДА Остатки.Счет.Валютный
ТОГДА Остатки.ВалютнаяСуммаОстаток * &Множитель
ИНАЧЕ Остатки.СуммаОстаток * &Множитель
КОНЕЦ > 0
ИНДЕКСИРОВАТЬ ПО
Субконто1,
Субконто2,
Субконто3,
Подразделение
В одной базе данный запрос без проблем открывается конструктором запросов и корректно отрабатывает в режиме «1С:Предприятие». В другой базе при попытке вызвать конструктор запроса система выдает ошибку парсинга метаданных, сообщая о несовместимости типов или невозможности прочитать составной тип субконто.
На первый взгляд кажется, что проблема кроется в составном типе поля Субконто3, который традиционно хранит документы расчетов (разнородные типы данных). Однако простое приведение типов через функцию ВЫРАЗИТЬ не решает проблему глобально, так как конструктор запросов падает еще на этапе инициализации виртуальной таблицы остатков.
Давайте разберем по шагам, почему поведение баз различается при одинаковом коде. Главная причина кроется в наличии так называемых «фантомных» (или битых) типов данных в свойствах конфигурации, в частности в Плане видов характеристик (ПВХ) «Виды субконто хозрасчетные» или непосредственно в Плане счетов.
Когда в процессе разработки или частых обновлений из конфигурации удаляется какой-либо объект метаданных (например, справочник бит_стр_АналитикаЗатрат) или этот объект исключается из состава типов характеристик ПВХ, платформа должна корректно очистить все ссылки на него во всех системных таблицах. Однако в силу различных причин (динамические обновления БД, сбои при реструктуризации, особенности конкретных релизов платформы) уникальный идентификатор (GUID) удаленного типа может остаться «записан» в бинарных полях системных таблиц конфигурации, таких как Config, ConfigSave или DBSchema.
Для платформы этот тип визуально перестает существовать — при просмотре типов в конфигураторе мы его не видим, либо видим пустую строчку со снятым или установленным флажком. Однако во внутренней структуре базы данных этот тип числится как доступный для использования.
Когда мы пытаемся открыть конструктор запросов для редактирования текста, парсер конструктора выполняет глубокий анализ схемы запроса. Обращаясь к виртуальной таблице РегистрБухгалтерии.Хозрасчетный.Остатки, конструктор пытается динамически определить все возможные типы данных для полей Субконто1, Субконто2 и Субконто3.
Для этого конструктор обращается к свойству «Тип значения характеристик» связанного плана видов характеристик (обычно это ПВХ «Виды субконто хозрасчетные»). Пытаясь построить внутреннее дерево типов и сопоставить виртуальные поля субконто с физическими таблицами СУБД, конструктор натыкается на «фантомный» GUID. Так как физическая таблица для удаленного объекта в СУБД уже отсутствует, а в схеме данных тип все еще зарегистрирован, парсер конструктора запросов аварийно завершает работу с ошибкой.
При этом сам запрос в режиме исполнения «1С:Предприятие» может работать абсолютно корректно и без ошибок возвращать данные. Это происходит потому, что исполняемый код СУБД работает по жестко построенному SQL-плану и не пытается производить визуальный анализ и сопоставление метаданных, как это делает интерактивный конструктор запросов в конфигураторе.
Многие разработчики при возникновении подобных ошибок сразу же запускают процедуру «Тестирование и исправление» (ТиИ). Однако в данном случае это не приносит результата. Давайте разберемся почему.
Стандартный механизм ТиИ предназначен главным образом для проверки и исправления таблиц данных (таблиц документов, справочников, записей регистров). Он отлично справляется с битыми ссылками внутри проведенных документов или проводок (например, может очистить несуществующую ссылку в субконто проводки, заменив ее на Неопределено). Но ТиИ не проверяет и не исправляет структуру метаданных, которая хранится в служебных системных таблицах конфигурации. Фантомный тип в описании типов ПВХ находится на уровне метаданных, поэтому ТиИ просто «не видит» эту проблему.
Проанализировав причины возникновения сбоя, рассмотрим несколько проверенных практических способов его устранения. Мы рекомендуем выполнять все описанные действия сначала на копии информационной базы.
Это самый быстрый и точечный метод исправления, если вы не хотите полностью перезаписывать конфигурацию базы данных.
ВидыСубконтоХозрасчетные).Этот способ применил автор темы для успешного решения своей проблемы (как описано в сообщении 8). Он эффективен, если ручной поиск фантомного типа затруднен.
.cf)..cf файл.ВидыСубконтоХозрасчетные (и, при необходимости, связанный План счетов Хозрасчетный). Установите флажки только напротив этих объектов.Если база данных подвергалась множественным динамическим обновлениям («демонским обновлениям») и в ней накопилось много системного «мусора», наиболее надежным решением будет полная перезапись таблиц конфигурации базы данных.
1c_v8.cf..dt).1c_v8.cf. Важно: используйте именно команду «Загрузить», а не «Сравнить и объединить», так как только полная загрузка конфигурации физически очищает и перезаписывает системные таблицы метаданных Config и таблицу схемы DBSchema, полностью удаляя любые скрытые фантомные ссылки.В редких случаях проблема кроется не в самой базе данных, а в некорректном кэшировании схемы метаданных на стороне сервера 1С:Предприятия или на локальном компьютере разработчика. Если кэш зафиксировал старую структуру ПВХ до удаления объектов, конструктор запросов будет обращаться по несуществующим адресам.
snccntx в каталоге кластера серверов). Запустите службу заново.%userprofile%\AppData\Local\1C\1Cv8 и %userprofile%\AppData\Roaming\1C\1Cv8.Применение одного из вышеперечисленных способов (в большинстве случаев помогает Способ 1 или Способ 2) позволит полностью устранить проблему со сбоем конструктора запросов, восстановить целостность структуры метаданных информационной базы и обеспечить стабильную работу механизмов бухгалтерского и управленческого учета взаиморасчетов.