ПРЕДПОСЫЛКИ:
Если вы используете ККМ, у вас возникает необходимость сверять отраженную выручку в 1С с предоставленными z-отчетами.
Сразу развею миф: «Если все чеки печатаются из 1С, то и сумма выручки всегда будет совпадать с z-отчетом». В жизни все не так.
Если у вас всего 1-5 контрольно кассовых машин (ККМ), можно ежедневно вручную бухгалтеру сверять выручку по бумажному z-отчету. Но если у вас более 100 ККМ, вопрос автоматизации по проверке достоверности отражения выручки, соблюдения кассовой дисциплины и своевременного пробития чеков становится очень остро. Человеческий фактор в данном случае становится просто катастрофическим.
К сожалению, типовые конфигурации 1С нам не предлагают возможность вести учет z-отчетов, что ж, реализуем сами.
Внедрение бизнес процесса по контролю и учету z-отчетов можно разделить на три этапа:
1. Создание в 1С документа "z-отчет" с ручным вводом информации.
2. Контроль и формирование отчетов по проверке показателей, которые можно извлечь из Z-отчета.
3. Автоматизация загрузки с ККМ данных о z-отчетах (их автоматическое создание в 1С).
Маленькая ремарка: Предоставленная ниже реализация z-отчета, является решением во времена ККМ с ЭКЛЗ и плавно была трансформирована (с обратной совместимостью) в решение для онлайн касс.
ПРИСТУПИМ:
1 ЭТАП
Создаем новый документ «_ZОтчетФискальный»
Реквизиты:
- Организация (СправочникСсылка.Организации)
- Подразделение (СправочникСсылка.Подразделения)
- ККМ (СправочникСсылка.КассыККМ)
- Накопление (Число15.2) В новых он-лайн ККМ это поле теперь называется ГРОСС ИТОГ
- Выручка (Число15.2)
- Возвраты (Число15.2)
- ВыручкаБезТоварныхЧеков (Число15.2) В этом поле отражают выручку, регистрируемую при поступлении средств от «оптовых» покупателей (ТОРГ12+ПКО).
- Неиспользованные (Число15.2)
- НомерГашения (Число10.0) В новых он-лайн ККМ это поле теперь называется НОМЕР СМЕНЫ.
- СуммаДокумента (Число15.2)
Для отображения в журнале
- НачальныеСведения (Булево) Этот реквизит необходим для обозначения вноса первого Z-отчета ККМ, или при смене ФН. При его установке не проверяется хронология отчетов по ККМ.
- Ответственный (СправочникСсылка.Пользователи)
- Комментарий (Строка)
В модуле объекта пишем код для проверки заполнения при проведении документа.
Функция НайтиПредыдущееГашение() Экспорт
СведенияОПредыдущем = Новый Структура("НомерГашения,Накопление,СсылкаНаДокумент");
СведенияОПредыдущем.НомерГашения=Неопределено;
СведенияОПредыдущем.Накопление=Неопределено;
СведенияОПредыдущем.СсылкаНаДокумент=Неопределено;
Если НЕ НачальныеСведения Тогда
Запрос=Новый Запрос("ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 1
|Ссылка,
|Дата,
|Организация,
|ККМ,
|Накопление,
|НомерГашения,
|Проведен
|ИЗ Документ._ZОтчетФискальный
|ГДЕ Дата<&ДатаКонец И Организация=&ВыбОрганизация И ККМ=&ВыбКасса И Проведен
|УПОРЯДОЧИТЬ ПО Дата УБЫВ");
Запрос.УстановитьПараметр("ВыбОрганизация",Организация);
Запрос.УстановитьПараметр("ВыбКасса",ККМ);
Запрос.УстановитьПараметр("ДатаКонец",Дата);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
СведенияОПредыдущем.НомерГашения=Выборка.НомерГашения;
СведенияОПредыдущем.Накопление=Выборка.Накопление;
СведенияОПредыдущем.СсылкаНаДокумент=Выборка.Ссылка;
КонецЕсли;
КонецЕсли;
Возврат СведенияОПредыдущем;
КонецФункции
Процедура ОбработкаПроведения(Отказ, Режим)
Если НЕ НачальныеСведения Тогда
СведенияОПредыдущем= НайтиПредыдущееГашение();
Если СведенияОПредыдущем.НомерГашения=Неопределено Тогда
Сообщить("Не найден предыдущий Финансовый отчет (гашение) для ККМ: "+Строка(ККМ));
Если НЕ РольДоступна("ПолныеПрава") Тогда
Отказ = Истина;
КонецЕсли;
Иначе
Если НомерГашения=СведенияОПредыдущем.НомерГашения Тогда
Сообщить("Уже существует документ с таким номером гашения для выбранной ККМ. Возможно вы задублировали документ.");
Сообщить("Ожидается номер "+Строка(СведенияОПредыдущем.НомерГашения+1));
Если НЕ РольДоступна("ПолныеПрава") Тогда
Отказ = Истина;
КонецЕсли;
ИначеЕсли (НомерГашения<СведенияОПредыдущем.НомерГашения) Тогда
Сообщить("Существует документ с более поздним номером гашения для выбранной ККМ. Отмените более поздние гашения, и проведите их в порядке возрастания номера гашения.");
Сообщить("Ожидается номер "+Строка(СведенияОПредыдущем.НомерГашения+1));
Если НЕ РольДоступна("ПолныеПрава") Тогда
Отказ = Истина;
КонецЕсли;
ИначеЕсли (НомерГашения>(СведенияОПредыдущем.НомерГашения+1)) Тогда
Сообщить("Существуют пропущенные номера гашения для выбранной ККМ. Преверте номер гашения или проведите гашения для пропущенных номеров.");
Сообщить("Ожидается номер "+Строка(СведенияОПредыдущем.НомерГашения+1));
Если НЕ РольДоступна("ПолныеПрава") Тогда
Отказ = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
//РасчВозврат=?(Касса.ОтражениеВозвратовВНакоплении=Перечисления.ВлияниеНаИтоги.Увеличивают,Возвраты,?(Касса.ОтражениеВозвратовВНакоплении=Перечисления.ВлияниеНаИтоги.Уменьшают,-Возвраты,0));
//РасчНеиспользованные=?(Касса.ОтражениеНеиспользованныхВНакоплении=Перечисления.ВлияниеНаИтоги.Увеличивают,Неиспользованные,?(Касса.ОтражениеНеиспользованныхВНакоплении=Перечисления.ВлияниеНаИтоги.Уменьшают,-Неиспользованные,0));
РасчВозврат = Возвраты; //Считаем что всегда увеличивают;
РасчНеиспользованные = 0; //Считаем что не влияют;
Если (Накопление<>(СведенияОПредыдущем.Накопление+Выручка+РасчВозврат+РасчНеиспользованные)) Тогда
Сообщить("Контроль накопления не пройден! Проверьте правильность внесения данных с бумажного чека ""Z-ОТЧЕТ (фискальный)""!");
Если НЕ РольДоступна("ПолныеПрава") Тогда
Отказ = Истина;
КонецЕсли;
КонецЕсли;
Конецесли;
КонецПроцедуры
Если вы обратили внимание, пользователь не может провести документ «_ZОтчетФискальный», если не выполняется математика или не соблюдается очередность отчетов.
Закомментированный код применялся при подсчете накопления в старых моделях ККМ с ЭКЛЗ, теперь в нем нет необходимости.
Документ «_ZОтчетФискальный» все проверки производит по указанной в документе конкретной кассе ККМ.
Небольшое лирическое отступление:
При эксплуатации касс АТОЛ 11Ф у нас неоднократно случались ошибки математики «ГРОСС ИТОГА» во время пробития z-отчета на ККМ, как правило при сбое (окончание бумаги или разряд аккумулятора).
Что ж, не беда, в нашем случае предусмотрен флаг «НачальныеСведения» в документе, при его установки документ позволяет начать отсчет номер гашения и накопление заново.
Вызов форма списка документа поместил в меню: Документы>Управление денежными средствами>Z-Отчеты
Форма списка выглядит так:
Форму документа я оформил в наглядном и понятном бухгалтеру виде:
Код формы документа:
Процедура ПриОткрытии()
Если НЕ ЭтоНовый() Тогда
НастройкаПравДоступа.ОпределитьДоступностьВозможностьИзмененияДокументаПоДатеЗапрета(ДокументОбъект, ЭтаФорма);
КонецЕсли;
Если ЭтоНовый() Тогда // проверить объект на то, что он еще не внесен в ИБ
Если НЕ ЗначениеЗаполнено(ДокументОбъект.Дата) Тогда
ДокументОбъект.Дата=ТекущаяДата();
Конецесли;
ДокументОбъект.Подразделение = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(глЗначениеПеременной("глТекущийПользователь"), "ОсновноеПодразделение");
ДокументОбъект.Организация = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(глЗначениеПеременной("глТекущийПользователь"), "ОсновнаяОрганизация");
ДокументОбъект.ККМ = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(глЗначениеПеременной("глТекущийПользователь"), "ОсновнаяКассаККМ");
ДокументОбъект.Ответственный = Пользователи.ТекущийПользователь();
КонецЕсли;
ОбновитьНадписи();
ОбновитьОбразецЧека();
КонецПроцедуры
Процедура ОбновитьНадписиПриИзмененииЭлемента(Элемент)
ОбновитьНадписи();
ОбновитьОбразецЧека();
КонецПроцедуры
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
ДокументОбъект.СуммаДокумента=ДокументОбъект.Выручка-ДокументОбъект.Возвраты-ДокументОбъект.Неиспользованные;
КонецПроцедуры
Функция НайтиПредыдущееГашениеНаСервере()
Возврат НайтиПредыдущееГашение();
КонецФункции
Процедура ОбновитьНадписи()
СведенияОПредыдущем= НайтиПредыдущееГашениеНаСервере();
ЭлементыФормы.РамкаСтарыйОтчет.Видимость=ДокументОбъект.НачальныеСведения;
Если СведенияОПредыдущем.НомерГашения=Неопределено Тогда
ЭлементыФормы.ПРНомерГашения.Заголовок="Номер гашения: Нет сведений";
ЭлементыФормы.ПРНакопление.Заголовок="Накопление: Нет сведений";
ЭлементыФормы.ПРНомерГашения.Видимость = Ложь;
ЭлементыФормы.ПРНакопление.Видимость = Ложь;
Иначе
ЭлементыФормы.ПРНомерГашения.Заголовок="Номер гашения: "+ФОРМАТ(СведенияОПредыдущем.НомерГашения,"ЧГ=");
ЭлементыФормы.ПРНакопление.Заголовок="Накопление: "+ФОРМАТ(СведенияОПредыдущем.Накопление)+" руб.";
ЭлементыФормы.ПРНомерГашения.Видимость = Истина;
ЭлементыФормы.ПРНакопление.Видимость = Истина;
КонецЕсли;
КонецПроцедуры
Процедура ОбновитьОбразецЧека()
ЭлементыФормы.ФД.Очистить();
ЭлементыФормы.ФД.ДобавитьСтроку("ИНН "+ДокументОбъект.Организация.ИНН);
ЭлементыФормы.ФД.ДобавитьСтроку("Z-ОТЧЕТ ФИСКАЛЬНЫЙ");
ЭлементыФормы.ФД.ДобавитьСтроку("ККМ "+ДокументОбъект.ККМ.СерийныйНомер);
ЭлементыФормы.ФД.ДобавитьСтроку("ЗАКР.СМЕНЫ "+ПРАВ("0000"+ФОРМАТ(ДокументОбъект.НомерГашения,"ЧГ="),4));
ЭлементыФормы.ФД.ДобавитьСтроку("");
ЭлементыФормы.ФД.ДобавитьСтроку("НАКОПЛЕНИЕ");
ЭлементыФормы.ФД.ДобавитьСтроку("ГРОСС-ИТОГ");
ЭлементыФормы.ФД.ДобавитьСтроку(" "+ПРАВ("..........."+ФОРМАТ(ДокументОбъект.Накопление,"ЧЦ=15; ЧДЦ=2; ЧРД=.; ЧН=0.00; ЧГ="),15));
ЭлементыФормы.ФД.ДобавитьСтроку("ВЫРУЧКА");
ЭлементыФормы.ФД.ДобавитьСтроку(" "+ПРАВ("..........."+ФОРМАТ(ДокументОбъект.Выручка,"ЧЦ=15; ЧДЦ=2; ЧРД=.; ЧН=0.00; ЧГ="),15));
ЭлементыФормы.ФД.ДобавитьСтроку(Формат(ДокументОбъект.Дата,"ДФ=""дд.ММ.гг ЧЧ.мм""")+"Ф");
ЭлементыФормы.ФД.ДобавитьСтроку("ВОЗВРАТЫ");
ЭлементыФормы.ФД.ДобавитьСтроку(" "+ПРАВ("..........."+ФОРМАТ(ДокументОбъект.Возвраты,"ЧЦ=15; ЧДЦ=2; ЧРД=.; ЧН=0.00; ЧГ="),15));
КонецПроцедуры
Если используете управляемые формы, то получать ИНН организации и серийный номер ККМ нужно через вызов функции на сервере.
2 ЭТАП
Создаем средства проверки и контроля данных в z-отчетах. Для этого у нас уже существует решение для бухгалтеров «ЕДИНАЯ ПРОВЕРКА ОШИБОК». Добавляем раздел по проверке сразу всех Z-отчетов, внесенных в 1С за определенный период.
Макет для вывода результатов проверки там выглядит как-то так:
Создаем процедуры по проверке документов «_ZОтчетФискальный»:
Перечисляю все варианты сообщений при проверке, по ним вы сможете понять, какие проверки производятся с документом z-отчет.
ОШИБКИ:
- В Z-отчете указаны неиспользованные чеки, но при этом ПКО оформлен на всю сумму выручки в Z-отчете на дату ХХХ
- В Z-отчете указаны оптовые продажи, но при этом ПКО с видом ""Прием розничной выручки"" оформлен на всю сумму выручки в Z-отчете на дату ХХХ
- Чистая выручка по Z-отчету ХХХ не соответсвует сумме ПКО ХХХ по кассе ККМ ХХХ на дату ХХХ
- Сумма неиспользованных чеков и оптовых продаж превышает общую выручку
- Сумма опта Z-отчетов ХХХ по подразделению ХХХ не сходится с суммой ПКО ХХХ на дату ХХХ
- Не найден предыдущий Финансовый отчет (гашение) для ККМ ХХХ
- Уже существует документ с таким номером гашения для выбранной ККМ. Возможно вы задублировали документ. Ожидается номер ХХХ
- Существует документ с более поздним номером гашения для выбранной ККМ. Отмените более поздние гашения, и проведите их в порядке возрастания номера гашения. Ожидается номер ХХХ
- Существуют пропущенные номера гашения для выбранной ККМ. Преверте номер гашения или проведите гашения для пропущенных номеров. Ожидается номер ХХХ
- Контроль накопления не пройден! Проверьте правильность внесения данных с бумажного чека "Z-ОТЧЕТ (фискальный)"!
ПРЕДУПРЕЖДЕНИЯ:
- По кассе ККМ ХХХ на дату ХХХ должен быть оформлен акт по неиспользованным кассовым чекам(КМ-3) на сумму ХХХ
- По кассе ККМ ХХХ на дату ХХХ должен быть оформлено заявление на возврат на сумму ХХХ
- По кассе ККМ ХХХ найдено несколько Z-отчетов с признаком "Начальные сведения"
Процедура ПроверкаZОтчетов(ТД,Макет)
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| _ZОтчетФискальный.ККМ КАК ККМ,
| МИНИМУМ(_ZОтчетФискальный.Дата) КАК Дата
|ИЗ
| Документ._ZОтчетФискальный КАК _ZОтчетФискальный
|ГДЕ
| _ZОтчетФискальный.Дата >= &Дата1
|
|СГРУППИРОВАТЬ ПО
| _ZОтчетФискальный.ККМ";
Запрос.Параметры.Вставить("Дата1",НачалоДня(ОбработкаОбъект.Период.ДатаНачала));
ТаблицаКасс = Запрос.Выполнить().Выбрать();
Пока ТаблицаКасс.Следующий() Цикл
Запрос = Новый Запрос;
Запрос.Текст="ВЫБРАТЬ
| ПКО.День КАК Дата,
| ЕСТЬNULL(ПКО.СуммаДокумента, 0) КАК СуммаПКО,
| ПКО.Контрагент КАК ККМ,
| ЕСТЬNULL(Отчеты.Выручка, 0) КАК СуммаОтчета,
| ЕСТЬNULL(Отчеты.Неиспользованные, 0) КАК Неиспользованные,
| ЕСТЬNULL(Отчеты.Возвраты, 0) КАК Возвраты,
| Отчеты.День КАК ДатаОтчета,
| Отчеты.ККМ КАК ККМОтчета,
| ЕСТЬNULL(Отчеты.ВыручкаБезТоварныхЧеков, 0) КАК Опт,
| ЕСТЬNULL(Отчеты.ВыручкаЧистая, 0) КАК СуммаОтчетаЧистая
|ИЗ
| (ВЫБРАТЬ
| _ZОтчетФискальный.Организация КАК Организация,
| _ZОтчетФискальный.ККМ КАК ККМ,
| СУММА(_ZОтчетФискальный.Выручка) КАК Выручка,
| НАЧАЛОПЕРИОДА(_ZОтчетФискальный.Дата, ДЕНЬ) КАК День,
| СУММА(_ZОтчетФискальный.Неиспользованные) КАК Неиспользованные,
| СУММА(_ZОтчетФискальный.Возвраты) КАК Возвраты,
| СУММА(_ZОтчетФискальный.ВыручкаБезТоварныхЧеков) КАК ВыручкаБезТоварныхЧеков,
| СУММА(_ZОтчетФискальный.Выручка - _ZОтчетФискальный.Неиспользованные - _ZОтчетФискальный.ВыручкаБезТоварныхЧеков) КАК ВыручкаЧистая
| ИЗ
| Документ._ZОтчетФискальный КАК _ZОтчетФискальный
| ГДЕ
| _ZОтчетФискальный.Дата МЕЖДУ &Дата1 И &Дата2
| И _ZОтчетФискальный.Проведен = ИСТИНА
| И _ZОтчетФискальный.Организация = &Организация
| И _ZОтчетФискальный.ККМ = &ККМ
|
| СГРУППИРОВАТЬ ПО
| _ZОтчетФискальный.Организация,
| _ZОтчетФискальный.ККМ,
| НАЧАЛОПЕРИОДА(_ZОтчетФискальный.Дата, ДЕНЬ)) КАК Отчеты
| ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
| ПриходныйКассовыйОрдер.Организация КАК Организация,
| ПриходныйКассовыйОрдер.Контрагент КАК Контрагент,
| СУММА(ПриходныйКассовыйОрдер.СуммаДокумента) КАК СуммаДокумента,
| НАЧАЛОПЕРИОДА(ПриходныйКассовыйОрдер.Дата, ДЕНЬ) КАК День
| ИЗ
| Документ.ПриходныйКассовыйОрдер КАК ПриходныйКассовыйОрдер
| ГДЕ
| ПриходныйКассовыйОрдер.Проведен = ИСТИНА
| И ПриходныйКассовыйОрдер.Дата МЕЖДУ &Дата1 И &Дата2
| И ПриходныйКассовыйОрдер.Организация = &Организация
| И ТИПЗНАЧЕНИЯ(ПриходныйКассовыйОрдер.Контрагент) = ТИП(Справочник.КассыККМ)
| И ПриходныйКассовыйОрдер.ВидОперации = ЗНАЧЕНИЕ(Перечисление.ВидыОперацийПКО.ПриходДенежныхСредствРозничнаяВыручка)
| И ПриходныйКассовыйОрдер.ОтражатьВБухгалтерскомУчете = ИСТИНА
| И ПриходныйКассовыйОрдер.Контрагент = &ККМ
|
| СГРУППИРОВАТЬ ПО
| ПриходныйКассовыйОрдер.Организация,
| ПриходныйКассовыйОрдер.Контрагент,
| НАЧАЛОПЕРИОДА(ПриходныйКассовыйОрдер.Дата, ДЕНЬ)) КАК ПКО
| ПО Отчеты.Организация = ПКО.Организация
| И Отчеты.ККМ = ПКО.Контрагент
| И Отчеты.День = ПКО.День";
Запрос.УстановитьПараметр("Организация",ОбработкаОбъект.Организация);
Запрос.УстановитьПараметр("Дата1",?(ТаблицаКасс.Дата>ОбработкаОбъект.Период.ДатаНачала,НачалоДня(ТаблицаКасс.Дата),НачалоДня(ОбработкаОбъект.Период.ДатаНачала)));
Запрос.УстановитьПараметр("Дата2",КонецДня(ОбработкаОбъект.Период.ДатаОкончания));
Запрос.УстановитьПараметр("ККМ",ТаблицаКасс.ККМ);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Если Выборка.СуммаПКО = Выборка.СуммаОтчета И Выборка.Неиспользованные >0 Тогда
ОбластьМакета = Макет.ПолучитьОбласть("Ошибка");
ОбластьМакета.Параметры.ОбъектаПроверки =?(Выборка.ККМ = Null,Выборка.ККМОтчета,Выборка.ККМ);
ОбластьМакета.Параметры.Ошибка ="В Z-отчете указаны неиспользованные чеки, но при этом ПКО оформлен на всю сумму выручки в Z-отчете на дату: " + Формат(?(Выборка.Дата = Null,Выборка.ДатаОтчета,Выборка.Дата),"ДФ=dd.MM.yy; ДЛФ=D");
ТД.Вывести(ОбластьМакета);
КонецЕсли;
Если Выборка.СуммаПКО = Выборка.СуммаОтчета И Выборка.Опт >0 Тогда
ОбластьМакета = Макет.ПолучитьОбласть("Ошибка");
ОбластьМакета.Параметры.ОбъектаПроверки =?(Выборка.ККМ = Null,Выборка.ККМОтчета,Выборка.ККМ);
ОбластьМакета.Параметры.Ошибка ="В Z-отчете указаны оптовые продажи, но при этом ПКО с видом ""Прием розничной выручки"" оформлен на всю сумму выручки в Z-отчете на дату: " + Формат(?(Выборка.Дата = Null,Выборка.ДатаОтчета,Выборка.Дата),"ДФ=dd.MM.yy; ДЛФ=D");
ТД.Вывести(ОбластьМакета);
КонецЕсли;
Если Выборка.СуммаПКО <> Выборка.СуммаОтчетаЧистая Тогда
ОбластьМакета = Макет.ПолучитьОбласть("Ошибка");
ОбластьМакета.Параметры.ОбъектаПроверки =?(Выборка.ККМ = Null,Выборка.ККМОтчета,Выборка.ККМ);
ОбластьМакета.Параметры.Ошибка ="Чистая выручка по Z-отчету: "+Выборка.СуммаОтчетаЧистая+" не соответсвует сумме ПКО: "+Выборка.СуммаПКО+" по кассе ККМ: "+Выборка.ККМ+" на дату: "+Формат(?(Выборка.Дата = Null,Выборка.ДатаОтчета,Выборка.Дата),"ДФ=dd.MM.yy; ДЛФ=D");
ТД.Вывести(ОбластьМакета);
КонецЕсли;
Если Выборка.Неиспользованные>0 Тогда
ОбластьМакета = Макет.ПолучитьОбласть("Предупреждение");
ОбластьМакета.Параметры.ОбъектаПроверки =?(Выборка.ККМ = Null,Выборка.ККМОтчета,Выборка.ККМ);
ОбластьМакета.Параметры.Ошибка ="По кассе ККМ: "+?(Выборка.ККМ = Null,Выборка.ККМОтчета,Выборка.ККМ)+" на дату: "+Формат(?(Выборка.Дата = Null,Выборка.ДатаОтчета,Выборка.Дата),"ДФ=dd.MM.yy; ДЛФ=D") + " должен быть оформлен акт по неиспользованным кассовым чекам(КМ-3) на сумму " + Выборка.Неиспользованные;
ТД.Вывести(ОбластьМакета);
КонецЕсли;
Если Выборка.Возвраты>0 Тогда
ОбластьМакета = Макет.ПолучитьОбласть("Предупреждение");
ОбластьМакета.Параметры.ОбъектаПроверки =?(Выборка.ККМ = Null,Выборка.ККМОтчета,Выборка.ККМ);
ОбластьМакета.Параметры.Ошибка ="По кассе ККМ: "+?(Выборка.ККМ = Null,Выборка.ККМОтчета,Выборка.ККМ)+" на дату: "+Формат(?(Выборка.Дата = Null,Выборка.ДатаОтчета,Выборка.Дата),"ДФ=dd.MM.yy; ДЛФ=D") + " должен быть оформлено заявление на возврат на сумму " + Выборка.Возвраты;
ТД.Вывести(ОбластьМакета);
КонецЕсли;
КонецЦикла;
Запрос = Новый Запрос;
ЕстьНачальный = Ложь;
Запрос.Текст="ВЫБРАТЬ
| _ZОтчетФискальный.Ссылка КАК Ссылка,
| _ZОтчетФискальный.НачальныеСведения КАК НачальныеСведения
|ИЗ
| Документ._ZОтчетФискальный КАК _ZОтчетФискальный
|ГДЕ
| _ZОтчетФискальный.ККМ = &ККМ
| И _ZОтчетФискальный.Дата МЕЖДУ &Дата1 И &Дата2
| И _ZОтчетФискальный.Проведен = ИСТИНА
| И _ZОтчетФискальный.Организация = &Организация";
Запрос.УстановитьПараметр("Дата1",?(ТаблицаКасс.Дата>ОбработкаОбъект.Период.ДатаНачала,НачалоДня(ТаблицаКасс.Дата),НачалоДня(ОбработкаОбъект.Период.ДатаНачала)));
Запрос.УстановитьПараметр("Дата2",КонецДня(ОбработкаОбъект.Период.ДатаОкончания));
Запрос.УстановитьПараметр("ККМ",ТаблицаКасс.ККМ);
Запрос.УстановитьПараметр("Организация",ОбработкаОбъект.Организация);
ZОтчеты = Запрос.Выполнить().Выбрать();
Пока ZОтчеты.Следующий() Цикл
Если ЕстьНачальный И ZОтчеты.НачальныеСведения Тогда
ОбластьМакета = Макет.ПолучитьОбласть("Предупреждение");
ОбластьМакета.Параметры.ОбъектаПроверки =?(Выборка.ККМ = Null,Выборка.ККМОтчета,Выборка.ККМ);
ОбластьМакета.Параметры.Ошибка ="По кассе ККМ " + ?(Выборка.ККМ = Null,Выборка.ККМОтчета,Выборка.ККМ) + " найдено несколько Z-отчетов с признаком ""Начальные сведения""";
ТД.Вывести(ОбластьМакета);
КонецЕсли;
Если ZОтчеты.НачальныеСведения Тогда
ЕстьНачальный = Истина;
КонецЕсли;
ПроверкаКорректностиZОтчетов(ZОтчеты.Ссылка,Выборка.ККМ,ТД,Макет);
КонецЦикла;
КонецЦикла;
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| МИНИМУМ(_ZОтчетФискальный.Дата) КАК Дата,
| _ZОтчетФискальный.ККМ.ПодразделениеОрганизации КАК Подразделение
|ИЗ
| Документ._ZОтчетФискальный КАК _ZОтчетФискальный
|ГДЕ
| _ZОтчетФискальный.Дата >= &Дата1
|
|СГРУППИРОВАТЬ ПО
| _ZОтчетФискальный.ККМ.ПодразделениеОрганизации";
Запрос.Параметры.Вставить("Дата1",НачалоДня(ОбработкаОбъект.Период.ДатаНачала));
ТаблицаПодразделений = Запрос.Выполнить().Выбрать();
Пока ТаблицаПодразделений.Следующий() Цикл
ЗапросОпт = Новый Запрос;
ЗапросОпт.Текст = "ВЫБРАТЬ
| ПКО.День КАК Дата,
| ЕСТЬNULL(ПКО.СуммаДокумента, 0) КАК СуммаПКО,
| Отчеты.День КАК ДатаОтчета,
| ЕСТЬNULL(Отчеты.ВыручкаБезТоварныхЧеков, 0) КАК Опт,
| Отчеты.Подразделение,
| ПКО.Подразделение КАК ПодразделениеПКО
|ИЗ
| (ВЫБРАТЬ
| _ZОтчетФискальный.Организация КАК Организация,
| НАЧАЛОПЕРИОДА(_ZОтчетФискальный.Дата, ДЕНЬ) КАК День,
| СУММА(_ZОтчетФискальный.ВыручкаБезТоварныхЧеков) КАК ВыручкаБезТоварныхЧеков,
| _ZОтчетФискальный.Подразделение КАК Подразделение
| ИЗ
| Документ._ZОтчетФискальный КАК _ZОтчетФискальный
| ГДЕ
| _ZОтчетФискальный.Дата МЕЖДУ &Дата1 И &Дата2
| И _ZОтчетФискальный.Проведен = ИСТИНА
| И _ZОтчетФискальный.Организация = &Организация
| И _ZОтчетФискальный.ВыручкаБезТоварныхЧеков > 0
| И _ZОтчетФискальный.Подразделение = &Подразделение
|
| СГРУППИРОВАТЬ ПО
| _ZОтчетФискальный.Организация,
| НАЧАЛОПЕРИОДА(_ZОтчетФискальный.Дата, ДЕНЬ),
| _ZОтчетФискальный.Подразделение) КАК Отчеты
| ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
| ПриходныйКассовыйОрдер.Организация КАК Организация,
| СУММА(ПриходныйКассовыйОрдер.СуммаДокумента) КАК СуммаДокумента,
| НАЧАЛОПЕРИОДА(ПриходныйКассовыйОрдер.Дата, ДЕНЬ) КАК День,
| ПриходныйКассовыйОрдер.Подразделение КАК Подразделение
| ИЗ
| Документ.ПриходныйКассовыйОрдер КАК ПриходныйКассовыйОрдер
| ГДЕ
| ПриходныйКассовыйОрдер.Проведен = ИСТИНА
| И ПриходныйКассовыйОрдер.Дата МЕЖДУ &Дата1 И &Дата2
| И ПриходныйКассовыйОрдер.Организация = &Организация
| И ПриходныйКассовыйОрдер.ВидОперации = ЗНАЧЕНИЕ(Перечисление.ВидыОперацийПКО.ОплатаПокупателя)
| И ПриходныйКассовыйОрдер.ОтражатьВБухгалтерскомУчете = ИСТИНА
| И ПриходныйКассовыйОрдер.Подразделение = &Подразделение
|
| СГРУППИРОВАТЬ ПО
| ПриходныйКассовыйОрдер.Организация,
| НАЧАЛОПЕРИОДА(ПриходныйКассовыйОрдер.Дата, ДЕНЬ),
| ПриходныйКассовыйОрдер.Подразделение) КАК ПКО
| ПО Отчеты.Организация = ПКО.Организация
| И Отчеты.День = ПКО.День
| И Отчеты.Подразделение = ПКО.Подразделение";
ЗапросОпт.УстановитьПараметр("Организация",ОбработкаОбъект.Организация);
ЗапросОпт.УстановитьПараметр("Дата1",?(ТаблицаКасс.Дата>ОбработкаОбъект.Период.ДатаНачала,НачалоДня(ТаблицаКасс.Дата),НачалоДня(ОбработкаОбъект.Период.ДатаНачала)));
ЗапросОпт.УстановитьПараметр("Дата2",КонецДня(ОбработкаОбъект.Период.ДатаОкончания));
ЗапросОпт.УстановитьПараметр("Подразделение",ПодразделениеОрганизацииВПодразделение(ТаблицаПодразделений.Подразделение));
ВыборкаОпт = ЗапросОпт.Выполнить().Выбрать();
Пока ВыборкаОпт.Следующий() Цикл
Если ВыборкаОпт.Опт <> ВыборкаОпт.СуммаПКО Тогда
ОбластьМакета = Макет.ПолучитьОбласть("Ошибка");
ОбластьМакета.Параметры.ОбъектаПроверки =?(ВыборкаОпт.Подразделение = Null,ВыборкаОпт.ПодразделениеПКО,ВыборкаОпт.Подразделение);
ОбластьМакета.Параметры.Ошибка ="Сумма опта Z-отчетов: " + ВыборкаОпт.Опт + " по подразделению " + ?(ВыборкаОпт.Подразделение = Null,ВыборкаОпт.ПодразделениеПКО,ВыборкаОпт.Подразделение) + " не сходится с суммой ПКО: " + ВыборкаОпт.СуммаПКО + " на дату " + Формат(?(ВыборкаОпт.Дата = Null,ВыборкаОпт.ДатаОтчета,ВыборкаОпт.Дата),"ДФ=dd.MM.yy; ДЛФ=D");
ТД.Вывести(ОбластьМакета);
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Процедура ПроверкаКорректностиZОтчетов(СсылкаНаОтчет,ККМ,ТД,Макет)
Если НЕ СсылкаНаОтчет.НачальныеСведения Тогда
СведенияОПредыдущем= НайтиПредыдущееГашение(СсылкаНаОтчет);
Если СведенияОПредыдущем.НомерГашения=Неопределено Тогда
ОбластьМакета = Макет.ПолучитьОбласть("Ошибка");
ОбластьМакета.Параметры.ОбъектаПроверки =СсылкаНаОтчет;
ОбластьМакета.Параметры.Ошибка ="Не найден предыдущий Финансовый отчет (гашение) для ККМ: "+Строка(ККМ);
ТД.Вывести(ОбластьМакета);
Иначе
Если СсылкаНаОтчет.НомерГашения=СведенияОПредыдущем.НомерГашения Тогда
ОбластьМакета = Макет.ПолучитьОбласть("Ошибка");
ОбластьМакета.Параметры.ОбъектаПроверки =СсылкаНаОтчет;
ОбластьМакета.Параметры.Ошибка ="Уже существует документ с таким номером гашения для выбранной ККМ. Возможно вы задублировали документ." + Символы.ПС + "Ожидается номер "+Строка(СведенияОПредыдущем.НомерГашения+1);
ТД.Вывести(ОбластьМакета);
ИначеЕсли (СсылкаНаОтчет.НомерГашения<СведенияОПредыдущем.НомерГашения) Тогда
ОбластьМакета = Макет.ПолучитьОбласть("Ошибка");
ОбластьМакета.Параметры.ОбъектаПроверки =СсылкаНаОтчет;
ОбластьМакета.Параметры.Ошибка ="Существует документ с более поздним номером гашения для выбранной ККМ. Отмените более поздние гашения, и проведите их в порядке возрастания номера гашения." + Символы.ПС + "Ожидается номер "+Строка(СведенияОПредыдущем.НомерГашения+1);
ТД.Вывести(ОбластьМакета);
ИначеЕсли (СсылкаНаОтчет.НомерГашения>(СведенияОПредыдущем.НомерГашения+1)) Тогда
ОбластьМакета = Макет.ПолучитьОбласть("Ошибка");
ОбластьМакета.Параметры.ОбъектаПроверки =СсылкаНаОтчет;
ОбластьМакета.Параметры.Ошибка ="Существуют пропущенные номера гашения для выбранной ККМ. Преверте номер гашения или проведите гашения для пропущенных номеров." + Символы.ПС + "Ожидается номер "+Строка(СведенияОПредыдущем.НомерГашения+1);
ТД.Вывести(ОбластьМакета);
КонецЕсли;
КонецЕсли;
РасчВозврат = СсылкаНаОтчет.Возвраты; //Считаем что всегда увеличивают;
РасчНеиспользованные = 0; //Считаем что не влияют;
Если (СсылкаНаОтчет.Накопление<>(СведенияОПредыдущем.Накопление+СсылкаНаОтчет.Выручка+РасчВозврат+РасчНеиспользованные)) Тогда
ОбластьМакета = Макет.ПолучитьОбласть("Ошибка");
ОбластьМакета.Параметры.ОбъектаПроверки =СсылкаНаОтчет;
ОбластьМакета.Параметры.Ошибка ="Контроль накопления не пройден! Проверьте правильность внесения данных с бумажного чека ""Z-ОТЧЕТ (фискальный)""!";
ТД.Вывести(ОбластьМакета);
КонецЕсли;
КонецЕсли;
Если СсылкаНаОтчет.Неиспользованные + СсылкаНаОтчет.ВыручкаБезТоварныхЧеков>СсылкаНаОтчет.Выручка Тогда
ОбластьМакета = Макет.ПолучитьОбласть("Ошибка");
ОбластьМакета.Параметры.ОбъектаПроверки =СсылкаНаОтчет;
ОбластьМакета.Параметры.Ошибка ="Сумма неиспользованных чеков и оптовых продаж превышает общую выручку";
ТД.Вывести(ОбластьМакета);
КонецЕсли;
КонецПроцедуры
Функция ПодразделениеОрганизацииВПодразделение(ПодразделениеОрганизации) Экспорт
Запрос=Новый запрос;
Запрос.Текст=
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| СоответствиеПодразделенийИПодразделенийОрганизаций.Подразделение,
| СоответствиеПодразделенийИПодразделенийОрганизаций.ПодразделениеОрганизации
|ИЗ
| РегистрСведений.СоответствиеПодразделенийИПодразделенийОрганизаций КАК СоответствиеПодразделенийИПодразделенийОрганизаций
|ГДЕ
| СоответствиеПодразделенийИПодразделенийОрганизаций.ПодразделениеОрганизации = &ПодразделениеОрганизации
| И СоответствиеПодразделенийИПодразделенийОрганизаций.Организация = &Организация";
Запрос.УстановитьПараметр("ПодразделениеОрганизации",ПодразделениеОрганизации);
Запрос.УстановитьПараметр("Организация",ПодразделениеОрганизации.Владелец);
Результат=Запрос.Выполнить().Выбрать();
Если Результат.Следующий() Тогда
Возврат Результат.Подразделение;
КонецЕсли;
Возврат Справочники.Подразделения.ПустаяСсылка();
КонецФункции
В результате можно формировать отчеты по проверки z- отчетов за любой период и вовремя устранять нарушения, не дожидаясь того, что на эти ошибки укажет вам ФНС.
Пример работы проверки:
3 ЭТАП
Когда количество касс вырастает к трехзначной цифре, остро назревает вопрос об автоматизации процесса получения сведений из z-отчета ККМ в автоматическом режиме.
Рассмотрим на примере POS систем АТОЛ и их ККМ.
Стандартный обмен текстовыми файлами с POS системами АТОЛ нам не особо помогает в процессе автоматизации.
При пробитии z-отчета POS система АТОЛа пишет в файл report.txt строку с кодом "63"
Пример строки:
1937;19.04.2018;20:09:47;63;1;195;2;;19;1379;1379;1379;9;2;0;0;0;;;1379;;0;8;0;;146/245/19;1;;;;;;;0;0 - Ошибок нет,0 - Ошибок нет,0 - Ошибок нет;;;;;;;;
Что можно из нее выдернуть :
дата - 19.04.2018,
время – 20:09:47
порядковый номер z-отчета - 19
выручку -1379.00
наличную часть выручки – 1379.00
накопление (ГРОСС ИТОГ) – такой информации АТОЛ в файл не записывает.
АТОЛ дает обработку «82АТОЛ.epf». В ее модуле объекта можно найти участок кода:
Функция ПрочитатьФайлВыгрузки(Объект, Файл, Отчет, Карты, Оплаты)
//++Комментарий автора
// Эта функция вызывается из Функции ЗагрузитьОтчет(Объект, Отчет, Карты = Неопределено, Оплаты = Неопределено)
// А она вызывается из функции «ЗагрузитьОтчетОПродажах» обработки конфигурации «ТОСервер»
//--Комментарий автора
//… разбор файла и запись его в таблицу «Отчет»…
ИначеЕсли ТипТранзакции = 63 Тогда
// Z-отчёт
Если Объект.Параметры.КритичныеОперации Тогда
Попытка
НомерСмены = Число(СтрПолучитьСтроку(ТекущаяСтрока, 9));
Выручка = Число(СтрПолучитьСтроку(ТекущаяСтрока, 10));
Наличность = Число(СтрПолучитьСтроку(ТекущаяСтрока, 11));
СменныйИтог = Число(СтрПолучитьСтроку(ТекущаяСтрока, 12));
Исключение
КонецПопытки;
КонецЕсли;
//....
КонецФункции
Для автоматизации загрузки Z-отчетов нужно передать по функциям пустую табличку с полями z-отчета и заполнить ее в указанном участке кода, а по возврату таблицы из функций - создать документ _ZОтчетФискальный в модуле обработки «ТОСервер».
Нам этот способ не подходил, поскольку АТОЛ не выдает накопление (ГРОСС ИТОГ) и возвраты, а их проверка была жизненно необходима.
Мы пошли другим путем, написали свою POS систему и сведения брали из драйвера ККМ в полном объеме в виде XML.
Пример xml
О обработках по автоматической загрузке данных с ККМ в 1С парсим приходящие файлы XML от ККМ.
Функция ЗагрузитьXML_reg(ПолноеИмяФайла) Экспорт
Перем ПостроитьДУМ,ДокументДУМ;
ПостроитьДУМ = Новый ПостроительDOM;
ПолучитьКорневойУзелXMLФайла(ПолноеИмяФайла,ПостроитьДУМ,ДокументДУМ);
Если ДокументДУМ=Неопределено Тогда
Возврат Ложь;
КонецЕсли;
КорневойУзел = ДокументДУМ.ПервыйДочерний;
Если КорневойУзел=Неопределено Тогда
Возврат Истина;
КонецЕсли;
//...
ЕстьОшибки = Ложь;
Если КорневойУзел.ЕстьДочерниеУзлы() Тогда
Для Каждого Узел_entry ИЗ КорневойУзел.ПолучитьЭлементыПоИмени("Документы") Цикл
Если Узел_entry.ЕстьДочерниеУзлы() Тогда
//…
Для Каждого Узел_requests ИЗ Узел_entry.ПолучитьЭлементыПоИмени("Документ.ZОтчёт") Цикл //ZОтчет
СтруктураДок = Новый Структура("ИДОтчета,НомерГашения,НомерСмены,ДатаККМ,НомерККМ,СуммаВыручки,СуммаВозвратов,СуммаВКассе,СуммаПрихода,СуммаНеобнуляемая","",0,0,Дата(1,1,1),"",0,0,0,0,0);
Для Каждого УзелРеквизитЭлемента ИЗ Узел_requests.ПолучитьЭлементыПоИмени("*") Цикл
ТекИмяУзла = УзелРеквизитЭлемента.ИмяУзла;
ТекЗначениеУзла = СокрЛП(УзелРеквизитЭлемента.ТекстовоеСодержимое);
Если ТекИмяУзла="ДатаККМ" Тогда
СтруктураДок.Вставить(ТекИмяУзла,ПолучитьДатуВремяИзСтроки(ТекЗначениеУзла,6));
ИначеЕсли ТекИмяУзла="СуммаВыручки" ИЛИ ТекИмяУзла="СуммаВозвратов" ИЛИ ТекИмяУзла="СуммаВКассе" ИЛИ ТекИмяУзла="СуммаПрихода" ИЛИ ТекИмяУзла="СуммаНеобнуляемая" Тогда
СтруктураДок.Вставить(ТекИмяУзла,Число(ТекЗначениеУзла));
Иначе
СтруктураДок.Вставить(ТекИмяУзла,СокрЛП(ТекЗначениеУзла));
КонецЕсли;
КонецЦикла;//конец шапки документа
НовЧек = ZОтчет.Добавить();
НовЧек.ИДОтчета =СтруктураДок.ИДОтчета;
НовЧек.НомерГашения =СтруктураДок.НомерГашения;
НовЧек.НомерСмены =СтруктураДок.НомерСмены;
НовЧек.ДатаККМ =СтруктураДок.ДатаККМ;
НовЧек.НомерККМ =СтруктураДок.НомерККМ;
НовЧек.СуммаВыручки =СтруктураДок.СуммаВыручки;
НовЧек.СуммаВозвратов =СтруктураДок.СуммаВозвратов;
НовЧек.СуммаВКассе =СтруктураДок.СуммаВКассе;
НовЧек.СуммаПрихода =СтруктураДок.СуммаПрихода;
НовЧек.СуммаНеобнуляемая =СтруктураДок.СуммаНеобнуляемая;
НовЧек.СсылкаZОтчета = ПолучитьДокZОтчетПоИД(СтруктураДок.ИдОтчета, СтруктураДок.ДатаККМ);
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат ЕстьОшибки;
КонецФункции
Отдельно загружает загруженную таблицу z-отчетов
Функция ПолучитьКассуККМПоСерийномуНомеру(СерНомер)
Запрос = новый Запрос;
Запрос.УстановитьПараметр("СерНомер", СерНомер);
Запрос.Текст= "ВЫБРАТЬ РАЗРЕШЕННЫЕ
| КассыККМ.Ссылка
|ИЗ
| Справочник.КассыККМ КАК КассыККМ
|ГДЕ
| КассыККМ.СерийныйНомер = &СерНомер";
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Количество() = 0 тогда
Сообщить("Не удалось найти кассу с серийным номером " + СерНомер +" !!!");
Возврат Неопределено;
ИначеЕсли Выборка.Количество() > 1 тогда
ТекстЗаголовок = "В базе найдено две Кассы с одинаковым серийным номером";
Сообщить(ТекстЗаголовок);
Возврат Неопределено;
ИначеЕсли Выборка.Количество() = 1 тогда
Выборка.Следующий();
Возврат Выборка.Ссылка;
КонецЕсли;
КонецФункции
Функция ПроверитьПервыйВвод(КассаККМ)
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ККМ", КассаККМ);
Запрос.Текст= "ВЫБРАТЬ
| _ZОтчетФискальный.Ссылка
|ИЗ
| Документ._ZОтчетФискальный КАК _ZОтчетФискальный
|ГДЕ
| _ZОтчетФискальный.ККМ = &ККМ
| И _ZОтчетФискальный.Проведен
| И НЕ _ZОтчетФискальный.ПометкаУдаления";
Выборка = Запрос.Выполнить().Выбрать();
Возврат НЕ Выборка.Следующий();
КонецФункции
Процедура СоздатьДокументыZОтчеты(Кнопка)
// Вставить содержимое обработчика.
Если ZОтчет.Количество() = 0 тогда
Сообщить("Нет Z-Отчетов доступных для загрузки");
КонецЕсли;
ДЛя Каждого Ст Из ZОтчет Цикл
Если Ст.СоздатьZ тогда
ДокZ = Документы._ZОтчетФискальный.СоздатьДокумент();
ЗаполнениеДокументов.ЗаполнитьШапкуДокумента(ДокZ);
ДокZ.Дата = Ст.ДатаККМ;
//Проверим организации
Если ДокZ.Организация.Пустая() тогда
Организация = Справочники.Организации.НайтиПоКоду("000000001");
Если Организация = Неопределено тогда
Сообщить("Не удалось установить организацию");
Возврат;
КонецЕсли;
ДокZ.Организация = Организация;
КонецЕсли;
КассаККМ = ПолучитьКассуККМПоСерийномуНомеру(Ст.НомерККМ);
Если не КассаККМ = Неопределено тогда
ДокZ.ККМ = КассаККМ;
Иначе
Возврат;
КонецЕсли;
Если ДокZ.Ответственный.Пустая() Тогда
ДокZ.Ответственный = ПараметрыСеанса.ТекущийПользователь;
КонецЕсли;
ДокZ.НачальныеСведения = ПроверитьПервыйВвод(ДокZ.ККМ);
ДокZ.Подразделение = Подразделение;
ДокZ.Возвраты = Ст.СуммаВозвратов;
ДокZ.Выручка = Ст.СуммаВыручки;
ДокZ.Накопление = Ст.СуммаНеобнуляемая;
ДокZ.НомерГашения = Ст.НомерСмены;
ДокZ.СуммаДокумента =ДокZ.Выручка-ДокZ.Возвраты-ДокZ.Неиспользованные;
ДокZ.Комментарий = "АвтоСоздание ##"+Ст.ИДОтчета+"##";
Попытка
ДокZ.Записать(РежимЗаписиДокумента.Проведение);
Ст.СоздатьZ = Ложь;
Исключение
Сообщить("Документ не удалось записать и провести!!! " + ОписаниеОшибки());
ДокZ.Записать(РежимЗаписиДокумента.Запись);
Ст.СоздатьZ = Ложь;
КонецПопытки;
Ст.СсылкаZОтчета = ДокZ.Ссылка;
КонецЕсли;
КонецЦикла;
КонецПроцедуры