В процессе работы с конфигурацией 1С:Управление нашей фирмой (УНФ) пользователи часто сталкиваются с ситуацией, когда дата документа Заказ покупателя не совпадает с фактическим моментом резервирования товаров. Например, заказ может быть принят в пятницу, а оператор обработал его и установил резерв только во вторник. При этом стандартный механизм 1С записывает движения в регистр накопления Запасы с периодом, равным дате документа (пятница).
Это создает серьезную проблему для складского учета: кладовщик не может сформировать отчет, который показал бы, какие товары были зарезервированы именно сегодня, чтобы физически отложить их в ячейки. В этой статье мы подробно разберем, почему так происходит, и рассмотрим несколько способов решения этой задачи: от изменения бизнес-логики до технических доработок системы.
Проанализируем устройство платформы 1С. В регистрах накопления основным временным измерением является поле Период. В типовых решениях это поле всегда привязано к дате документа-регистратора. Если мы проводим документ неоперативно (т.е. за прошедшую дату), все записи в регистрах получат именно эту «прошлую» дату. Платформа 1С является транзакционной системой, но она не хранит дату «физической записи» в стандартных полях регистров накопления, доступных для простых запросов. Это сделано для обеспечения целостности бухгалтерского и управленческого учета, где важнее дата совершения хозяйственной операции, а не дата ввода данных в компьютер.
Самый правильный с точки зрения методики 1С способ — это разделение функций заказа и резервирования. Рассмотрим, как это работает. Вместо того чтобы устанавливать резерв непосредственно в документе Заказ покупателя (через форму распределения запасов, часто называемую пользователями «глазом»), следует использовать подчиненный документ.
Заказ покупателя (дата — пятница).Резервирование запасов.В этом случае в регистре Запасы появятся записи с периодом «вторник», и кладовщик легко увидит их в отчете за день. Этот метод не требует программирования и сохраняет типовую конфигурацию на поддержке. Единственный минус — пользователю приходится делать «лишние» клики мышкой, что иногда вызывает сопротивление персонала.
Если бизнес-процесс требует, чтобы резервирование делалось именно в заказе, и мы не можем заставить пользователей создавать лишние документы, воспользуемся механизмом расширений. Мы добавим в регистр накопления Запасы новый реквизит, который будет хранить реальное время записи.
Рассмотрим пошагово реализацию этого метода:
Запасы.ДатаФактическойЗаписи (тип: Дата, состав даты: Дата и время).Пример кода для заполнения этого поля в модуле набора записей регистра:
&После("ПередЗаписью")
Процедура Расш1_ПередЗаписью(Отказ, Замещение)
Для Каждого Запись Из ЭтотОбъект Цикл
// Устанавливаем текущую дату сервера для каждой строки движений
Запись.ДатаФактическойЗаписи = ТекущаяДатаСеанса();
КонецЦикла;
КонецПроцедуры
После этого в любом отчете, построенном на схеме компоновки данных (СКД), мы сможем вытянуть это поле и использовать его для фильтрации. Теперь, даже если заказ от пятницы, в колонке ДатаФактическойЗаписи у движений по резерву будет стоять вторник.
Если изменения в структуре данных (добавление реквизитов) недопустимы, можно попробовать получить данные из Журнала регистрации. В нем фиксируются все транзакции проведения документов с указанием точного времени. Выясним, как это реализовать программно.
Для получения даты транзакции конкретного документа можно использовать следующий подход:
Фильтр = Новый Структура;
Фильтр.Вставить("Данные", СсылкаНаЗаказ);
Фильтр.Вставить("Событие", "_$Data$_.Post"); // Событие проведения
ТаблицаСобытий = Новый ТаблицаЗначений;
ВыгрузитьЖурналРегистрации(ТаблицаСобытий, Фильтр, "Дата, Пользователь, Данные");
Если ТаблицаСобытий.Количество() > 0 Тогда
// Последняя запись в таблице покажет самый свежий момент проведения
ПоследнееПроведение = ТаблицаСобытий[ТаблицаСобытий.Количество() - 1].Дата;
КонецЕсли;
Важное замечание: Этот метод крайне медленный. Использовать его в оперативных отчетах, которыми кладовщик пользуется постоянно, не рекомендуется, так как чтение больших файлов журнала регистрации создаст высокую нагрузку на сервер.
В конфигурации УНФ встроена подсистема «Версионирование объектов». Если ее включить для документа Заказ покупателя, система будет сохранять состояние документа при каждом проведении. Проанализируем возможности этого метода:
ВерсииОбъектов, чтобы найти момент, когда в табличной части Запасы (у заказа) впервые заполнилось поле Резерв.Этот способ позволяет восстановить хронологию без изменения кода, но требует сложных запросов для сопоставления версий объекта с движениями регистра.
Подведем итог нашему анализу ситуации с датами резервирования в 1С:УНФ:
Резервирование запасов. Это самое чистое решение, которое не создает проблем при обновлениях и корректно отражает данные в типовых отчетах.Запасы. Это оптимальный вариант, если нужно сохранить текущий интерфейс работы пользователя «в одном окне» заказа, обеспечив при этом склад достоверными данными.При реализации любого из этих решений помните, что Момент времени в 1С (комбинация даты и ссылки на документ) служит для упорядочивания записей в пределах одной секунды, но он не поможет узнать реальный день недели, когда была нажата кнопка «Провести», если дата в шапке документа была изменена вручную.