Почему не работает вызов функции из общего модуля и как правильно заполнять дату в документах 1С

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

При разработке в среде 1С:Предприятие 8 начинающие программисты часто сталкиваются с ситуацией, когда созданный общий модуль отказывается работать, выдавая ошибку «Переменная не определена». Рассмотрим типичный сценарий: вы создали общий модуль Даты, написали там экспортную функцию для получения текущего времени, но при попытке вызвать её из формы документа система сообщает об ошибке. Разберем детально, почему это происходит, и выясним, как организовать заполнение данных профессионально.

Причина ошибки «Переменная не определена (Даты)»

Проанализируем ситуацию: код в модуле формы выполняется на стороне клиента (директива &НаКлиенте), а общий модуль по умолчанию может быть настроен на выполнение только на сервере. В 1С клиентское приложение и сервер — это разные процессы, и клиент «не видит» серверные модули, если для них не установлены специальные разрешения.

Чтобы исправить эту проблему, нам необходимо настроить свойства общего модуля. Рассмотрим по шагам:

  1. Найдем в дереве конфигурации наш общий модуль Даты.
  2. Откроем палитру свойств (правой кнопкой мыши — Свойства).
  3. Проверим флаги компиляции. Для того чтобы модуль был доступен в процедуре ПриОткрытии (которая выполняется на клиенте), должен быть установлен флаг Клиент (управляемое приложение).
  4. Если функция внутри модуля обращается к серверным данным или должна выполняться именно на сервере, но вызываться с клиента, необходимо установить флаг Вызов сервера.

Важное замечание: Если у модуля установлен признак Глобальный, то обращение к его методам происходит без указания имени модуля. То есть вместо Даты.ВозвратТекущейДаты() нужно писать просто ВозвратТекущейДаты(). Использование точки при включенном флаге «Глобальный» также приведет к ошибке.

Разница между ТекущаяДата() и ТекущаяДатаСеанса()

В коде автора используется функция ТекущаяДата(). Проанализируем, почему в многопользовательских системах это может стать проблемой. Рассмотрим пример: сервер 1С находится в Москве (UTC+3), а бухгалтер работает во Владивостоке (UTC+10). Функция ТекущаяДата() вернет время сервера (московское), что будет некорректно для дальневосточного филиала.

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

Методологически верное решение: Модуль объекта

Перейдем к самому важному аспекту — архитектуре. Заполнение реквизитов документа в событии формы ПриОткрытии или ПриСозданииНаСервере считается плохой практикой (так называемым «говнокодом»). Выясним причину:

Если мы прописываем логику в форме, она сработает только тогда, когда пользователь открывает документ интерактивно. Если же документ будет создаваться программно (например, на основании другого документа, через обработку загрузки данных из Excel или через веб-сервис), форма не откроется, код не выполнится, и поле Дата останется пустым.

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

Разберем пример кода в модуле объекта:


Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
    // Проверяем, что это именно новый документ, а не перезаполнение существующего
    Если ЭтоНовый() Тогда
        // Используем ТекущаяДатаСеанса для учета часового пояса
        Дата = ТекущаяДатаСеанса();
    КонецЕсли;
КонецПроцедуры

Оптимизация клиент-серверного взаимодействия

Вызов общего модуля из процедуры ПриОткрытии на клиенте порождает лишний «сетевой прыжок» (round-trip). Это замедляет работу системы, так как компьютер пользователя должен отправить запрос серверу, дождаться ответа и только потом продолжить работу. Проанализируем, как этого избежать.

Если вам все же необходимо донастроить что-то именно в форме, используйте событие ПриСозданииНаСервере. Это событие выполняется один раз при инициализации формы на стороне сервера, и здесь можно обращаться к любым серверным общим модулям без лишних сетевых задержек.

Посмотрим на пример в модуле формы:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // Если документ новый и дата еще не заполнена (например, в ОбработкаЗаполнения)
    Если Объект.Ссылка.Пустая() И Объект.Дата = '00010101' Тогда
        Объект.Дата = ТекущаяДатаСеанса();
    КонецЕсли;
КонецПроцедуры

Использование Библиотеки Стандартных Подсистем (БСП)

В современных конфигурациях (таких как УТ 11, ERP, БП 3.0) уже внедрена БСП. Нам не нужно создавать собственные велосипеды для получения даты. Рассмотрим, как это реализовано профессионалами. В БСП существует общий модуль ОбщегоНазначения, который уже имеет все необходимые флаги компиляции.

Вместо создания своего модуля Даты, мы можем вызвать:

ОбщегоНазначения.ТекущаяДатаСеанса()

Итоги и рекомендации

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

  1. Проверяйте контекст: Если вызываете модуль с клиента, у него должен стоять флаг Клиент. Если модуль должен выполнить код на сервере по запросу клиента — флаг Вызов сервера.
  2. Выбирайте правильное место: Основную логику заполнения реквизитов (Дата, Склад, Организация, Ответственный) всегда пишите в Модуле объекта в процедуре ОбработкаЗаполнения.
  3. Соблюдайте точность времени: Всегда используйте ТекущаяДатаСеанса() вместо ТекущаяДата(), чтобы избежать проблем с часовыми поясами.
  4. Минимизируйте вызовы: Избегайте обращений к серверным функциям из клиентских событий ПриОткрытии или НаКлиенте, если это не продиктовано логикой интерфейса.

Соблюдение этих простых, но важных правил позволит вам создавать надежные и производительные решения на платформе 1С, которые не «сломаются» при обновлении или изменении способа записи данных.

← На главную