Почему один и тот же запрос в 1С работает в одной базе, но выдает ошибку в конструкторе в другой?

Программист 1С v8.3 (Управляемые формы) Бухгалтерский учет IT и автоматизация бизнеса
← На главную

Каждый разработчик 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-плану и не пытается производить визуальный анализ и сопоставление метаданных, как это делает интерактивный конструктор запросов в конфигураторе.

Почему Тестирование и Исправление (ТиИ) не помогает?

Многие разработчики при возникновении подобных ошибок сразу же запускают процедуру «Тестирование и исправление» (ТиИ). Однако в данном случае это не приносит результата. Давайте разберемся почему.

Стандартный механизм ТиИ предназначен главным образом для проверки и исправления таблиц данных (таблиц документов, справочников, записей регистров). Он отлично справляется с битыми ссылками внутри проведенных документов или проводок (например, может очистить несуществующую ссылку в субконто проводки, заменив ее на Неопределено). Но ТиИ не проверяет и не исправляет структуру метаданных, которая хранится в служебных системных таблицах конфигурации. Фантомный тип в описании типов ПВХ находится на уровне метаданных, поэтому ТиИ просто «не видит» эту проблему.

Методы решения проблемы

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

Способ 1. Ручное исправление типов в Плане видов характеристик

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

  1. Откройте конфигуратор вашей проблемной информационной базы.
  2. Найдите План видов характеристик, который назначен в качестве видов субконто для вашего плана счетов (обычно это ВидыСубконтоХозрасчетные).
  3. Откройте палитру свойств этого ПВХ и перейдите к свойству «Тип значения характеристик» (нажмите кнопку выбора типа «...»).
  4. В открывшемся окне выбора типов внимательно прокрутите весь список доступных объектов (справочники, документы и т.д.).
  5. Ищите «странные» строки. Это может быть пустая строка без названия, но с установленным или снятым флажком (обычно располагается в самом конце списков метаданных), либо тип, помеченный как удаленный.
  6. Снимите флажок с этой «пустой» строки. Если флажок не стоит, попробуйте установить его, нажать «ОК», затем снова зайти, снять флажок и опять нажать «ОК» (это заставит платформу перезаписать структуру типов).
  7. Нажмите кнопку «ОК» для сохранения изменений типа значений характеристик.
  8. Обновите конфигурацию базы данных (клавиша F7). При обновлении платформа выполнит реструктуризацию таблиц субконто и полностью вычистит некорректный GUID из базы данных.

Способ 2. Обновление Плана видов характеристик из «чистой» конфигурации

Этот способ применил автор темы для успешного решения своей проблемы (как описано в сообщении 8). Он эффективен, если ручной поиск фантомного типа затруднен.

  1. Возьмите заведомо исправную базу (например, демонстрационную базу того же релиза или конфигурацию без доработок) и выгрузите ее файл конфигурации (.cf).
  2. В проблемной базе запустите режим Сравнения и объединения конфигураций (меню Конфигурация -> Сравнить, объединить с конфигурацией из файла...) и выберите полученный .cf файл.
  3. В открывшемся дереве сравнения снимите флажки со всех объектов.
  4. Найдите План видов характеристик ВидыСубконтоХозрасчетные (и, при необходимости, связанный План счетов Хозрасчетный). Установите флажки только напротив этих объектов.
  5. Обратите внимание на отчет о сравнении свойств типов. Платформа покажет различие в типах, где со стороны вашей базы будет отображаться пустая строка (тот самый битый тип).
  6. Выполните объединение конфигураций.
  7. Если в вашей базе присутствовали нетиповые (добавленные вами) справочники или документы, которые должны использоваться в качестве субконто, добавьте их обратно в типы значений характеристик ПВХ вручную.
  8. Обновите конфигурацию базы данных (F7).

Способ 3. Загрузка конфигурации «начисто»

Если база данных подвергалась множественным динамическим обновлениям («демонским обновлениям») и в ней накопилось много системного «мусора», наиболее надежным решением будет полная перезапись таблиц конфигурации базы данных.

  1. В исправной базе (где конструктор запросов работает без ошибок) выполните выгрузку конфигурации в файл (меню Конфигурация -> Выгрузить конфигурацию в файл...) и сохраните файл 1c_v8.cf.
  2. В проблемной базе откройте конфигуратор и обязательно сделайте резервную копию (выгрузку .dt).
  3. Снимите конфигурацию с поддержки (если это требуется для перезаписи служебных таблиц схем метаданных) или убедитесь, что конфигурация открыта для редактирования.
  4. Выполните команду Конфигурация -> Загрузить конфигурацию из файла... и укажите сохраненный ранее исправный файл 1c_v8.cf. Важно: используйте именно команду «Загрузить», а не «Сравнить и объединить», так как только полная загрузка конфигурации физически очищает и перезаписывает системные таблицы метаданных Config и таблицу схемы DBSchema, полностью удаляя любые скрытые фантомные ссылки.
  5. Обновите конфигурацию базы данных (F7) и согласитесь с изменениями в структуре метаданных.

Способ 4. Очистка кэша метаданных

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

  1. Закройте все сеансы работы с проблемной базой данных (включая конфигуратор).
  2. Если база клиент-серверная, остановите службу сервера 1С:Предприятия и удалите содержимое папки временных файлов сервера (папка snccntx в каталоге кластера серверов). Запустите службу заново.
  3. На клиентском компьютере удалите проблемную базу из списка баз в стартовом окне 1С и добавьте ее заново. При этом для базы сгенерируется новый уникальный идентификатор кэша, и все локальные временные файлы метаданных будут созданы заново в каталоге пользователя %userprofile%\AppData\Local\1C\1Cv8 и %userprofile%\AppData\Roaming\1C\1Cv8.

Применение одного из вышеперечисленных способов (в большинстве случаев помогает Способ 1 или Способ 2) позволит полностью устранить проблему со сбоем конструктора запросов, восстановить целостность структуры метаданных информационной базы и обеспечить стабильную работу механизмов бухгалтерского и управленческого учета взаиморасчетов.

← На главную