При разработке и сопровождении конфигураций на платформе 1С:Предприятие 7.7 разработчики нередко сталкиваются с ситуацией, когда попытка получить номер документа через функцию ТекущийДокумент() приводит к непредсказуемым результатам: на одном компьютере выводится текстовое представление, а на другом — пустое поле или пробел. Разберем детально, как устроена работа этой функции, почему нельзя использовать ее для получения номера и как устранить возможные повреждения информационной базы.
Проанализируем синтаксис и назначение функции ТекущийДокумент(). Согласно синтакс-помощнику платформы 1С 7.7, данная функция возвращает значение позиционированного текущего документа (ссылочный тип данных), а не его строковый реквизит.
Рассмотрим, как ведет себя платформа в различных контекстах выполнения кода:
ТекущийДокумент() возвращает ссылку на текущий открытый или проводимый документ базы данных.СоздатьОбъект(): вызов выполняется как метод конкретного объекта — Док.ТекущийДокумент() после того, как объект был позиционирован (например, с помощью методов НайтиДокумент(), ВыбратьДокументы() или ПолучитьДокумент()).Когда мы пытаемся выполнить неявное преобразование ссылки в строку (например, используя операторы "" + ТекущийДокумент() или функцию СокрЛП(ТекущийДокумент())), платформа 1С 7.7 формирует системное представление документа. Это представление зависит от вида документа, настроек нумератора, периодичности номеров в метаданных и синонимов. Оно не гарантирует вывод чистого номера документа.
Для гарантированного получения номера документа необходимо обращаться непосредственно к системному реквизиту НомерДок. Рассмотрим несколько типовых сценариев.
Сценарий 1. Получение номера внутри модуля самого документа или его формы
В контексте самого документа все его реквизиты шапки и системные свойства доступны напрямую как локальные переменные. Вызывать функцию ТекущийДокумент() для чтения собственного номера избыточно.
// В модуле формы или модуле документа:
ТекНомер = НомерДок;
Сообщить("Номер текущего документа: " + ТекНомер);
Сценарий 2. Получение номера через ссылку на документ
Если у нас есть ссылка на документ (полученная из другого объекта, журнала или реквизита), обращение к номеру выполняется через точку:
// Получение номера через ссылку:
ТекСсылка = ТекущийДокумент();
Если ПустоеЗначение(ТекСсылка) = 0 Тогда
ТекНомер = ТекСсылка.НомерДок;
Сообщить("Номер документа: " + ТекНомер);
КонецЕсли;
Сценарий 3. Работа через объект метаданных в отчетах и обработках
При выборке документов во внешних отчетах или обработках правильный алгоритм выглядит следующим образом:
Док = СоздатьОбъект("Документ.Оплата");
Если Док.НайтиПоНомеру("1084169", ТекущаяДата()) = 1 Тогда
ТекНомер = Док.НомерДок;
ТекСсылка = Док.ТекущийДокумент();
Сообщить("Найден документ № " + ТекНомер);
КонецЕсли;
Если один и тот же программный код на одной машине возвращает строковое значение, а на другой — пустую строку, разберем ключевые причины такого поведения:
1SJOURN.CDX): В файловом режиме базы DBF 1С 7.7 связь ссылок и их представлений строится через индексы. При аварийном завершении сеанса или сбоях сети индексы могут повреждаться. В результате функция ТекущийДокумент() не может корректно спозиционироваться на записи в таблице журнала и возвращает пустое значение.Если код написан корректно, но платформа продолжает возвращать пустые значения для существующих документов, выполним регламентные процедуры по восстановлению целостности данных:
*.cdx в каталоге базы данных и запустим 1С:Предприятие в монопольном режиме — программа автоматически перестроит все индексы.ПустоеЗначение() или метода Выбран().