В процессе работы с программой 1С:Зарплата и управление персоналом 3.1 пользователи часто сталкиваются с необходимостью оперативного контроля сумм налога непосредственно из списка документов. В документе Ведомость в банк в подвале табличной части наглядно представлены итоги: «Сумма к выплате» и «НДФЛ к перечислению». Однако при переходе в общий журнал (список) ведомостей мы видим только общую сумму к выплате по документу, а колонка с налогом отсутствует.
Попытки вывести этот показатель стандартным действием Изменить форму не приносят результата, так как реквизит налога отсутствует в шапке документа и рассчитывается динамически по табличной части. В этой статье мы подробно разберем, как решить эту задачу без изменения конфигурации, рассмотрим альтернативные методы анализа данных через отчеты, а также решим техническую проблему программного позиционирования курсора на последней строке табличного документа.
Для начала проанализируем структуру метаданных документа. Реквизит СуммаДокумента (сумма к выплате) является реквизитом шапки. Он записывается непосредственно в таблицу базы данных, соответствующую документу, и поэтому легко извлекается платформой для отображения в динамическом списке журнала.
В отличие от него, сумма НДФЛ к перечислению — это агрегируемое значение. Налог рассчитывается как сумма строк табличной части НДФЛ (или берется из соответствующих регистров накопления, таких как РасчетыНалогоплательщиковСНДФЛ). Поскольку этого поля нет в шапке, платформа физически не может вывести его в стандартный список без дополнительного программного кода или изменения структуры данных.
Рассмотрим по шагам несколько практических способов обхода этого ограничения.
Если вам требуется быстро вывести информацию в список силами самого пользователя, можно применить проверенный лайфхак с использованием дополнительных реквизитов. Настроим этот функционал вместе:
Ведомость в банк (или Ведомость в кассу, если вы используете разные виды выплат).Число (длина 15, точность 0, неотрицательное). Нажмем Записать и закрыть.Ссылка, выделим его и нажмем кнопку Добавить поля. В списке доступных полей отметим флажком наш новый дополнительный реквизит и нажмем ОК.Важное ограничение метода: Поскольку данный реквизит является дополнительным, программа не умеет заполнять его автоматически при проведении ведомости «из коробки». Пользователям придется вносить сумму НДФЛ в это поле вручную при подготовке документа. Этот способ отлично подходит для небольших организаций с малым объемом документооборота.
Для автоматизации процесса без снятия конфигурации с поддержки мы можем использовать механизм расширений (.cfe). Расширение позволяет динамически изменять поведение программы, добавляя вычисляемые поля в динамические списки или перехватывая события формы.
Проанализируем алгоритм работы такого расширения. В форму списка ведомостей добавляется новая колонка. При получении данных на сервере расширение выполняет запрос к табличным частям отображаемых документов и суммирует налог:
&НаСервере
Процедура Расш_ПриПолученииДанныхНаСервереПосле(ИмяКомпоненты, ОформленияСтрок, Данные)
// Собираем массив ссылок отображаемых ведомостей
МассивВедомостей = Новый Массив;
Для Каждого СтрокаОформления Из ОформленияСтрок Цикл
МассивВедомостей.Добавить(СтрокаОформления.Ключ);
КонецЦикла;
// Запросом получаем суммы удержанного НДФЛ по этим ведомостям
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| НДФЛ.Ссылка КАК Ведомость,
| СУММА(НДФЛ.Налог) КАК СуммаНДФЛ
|ИЗ
| Документ.ВедомостьВБанк.НДФЛ КАК НДФЛ
|ГДЕ
| НДФЛ.Ссылка В(&МассивВедомостей)
|ГРУППИРОВАТЬ ПО
| НДФЛ.Ссылка";
Запрос.УстановитьПараметр("МассивВедомостей", МассивВедомостей);
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
// Заполняем созданную в расширении колонку на форме списка
Для Каждого СтрокаОформления Из ОформленияСтрок Цикл
НайденнаяСтрока = РезультатЗапроса.Найти(СтрокаОформления.Ключ, "Ведомость");
Если НайденнаяСтрока <> Неопределено Тогда
СтрокаОформления.Значение.Ячейки.Расш_КолонкаНДФЛ.УстановитьТекст(Формат(НайденнаяСтрока.СуммаНДФЛ, "ЧДЦ=2"));
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Подключить такое расширение может администратор системы в режиме «1С:Предприятие» через меню Администрирование – Печатные формы, отчеты и обработки – Расширения, не прерывая работу пользователей и сохраняя возможность автоматического обновления конфигурации.
Если доработки оперативно внедрить невозможно, наиболее эффективным решением будет использование типового отчета «Удержанный НДФЛ» (раздел Налоги и взносы – Отчеты по налогам и взносам).
Этот отчет по умолчанию группирует информацию по датам удержания (выплаты) и конкретным документам-ведомостям. Настроив один раз этот отчет и сохранив его вариант, вы сможете в один клик получать реестр всех ведомостей за месяц с детализацией сумм выплаты и сумм удержанного налога, избегая необходимости открывать каждый документ вручную.
Перейдем к разбору технического вопроса, который обсуждался во второй части темы. Автор попытался программно спозиционировать фокус на последней выводимой строке табличного документа в печатной форме, используя следующий код:
Пока Выборка.Следующий() Цикл
ОбластьДетальныхЗаписей.Параметры.Заполнить(Выборка);
ОбластьТекущейСтроки = ТабДок.Вывести(ОбластьДетальныхЗаписей);
КонецЦикла;
Горизонталь=ОбластьТекущейСтроки.Верх;
ТабДок.ТекущаяОбласть = ТабДок.Область(Горизонталь,2,Горизонталь,3);
Выясним, почему данный код не приносит желаемого результата на практике. Существует две основные причины:
ТекущаяОбласть для объекта ТабличныйДокумент имеет смысл только тогда, когда документ уже визуализирован на клиенте. Если данный алгоритм выполняется на сервере в момент формирования печатной формы, то при передаче готового макета на клиентскую сторону настройки фокуса сбросятся к значениям по умолчанию (на первую ячейку).ТекущаяОбласть не всегда принудительно заставляет интерфейс прокрутить экран до нужной позиции. Чтобы гарантировать видимость ячейки пользователю, необходимо использовать метод Показать().Рассмотрим правильный вариант реализации позиционирования. Нам необходимо разделить логику формирования документа на сервере и последующую работу с ним на клиенте:
// На сервере формируем документ и возвращаем его на клиент
&НаСервере
Функция СформироватьРеестрНаСервере()
ТабДок = Новый ТабличныйДокумент;
// ... логика вывода областей в цикле ...
Возврат Новый Структура("Документ, ПоследняяСтрока", ТабДок, Горизонталь);
КонецФункции
// На клиенте открываем форму, отображаем документ и устанавливаем фокус
&НаКлиенте
Процедура СформироватьИПоказать()
Результат = СформироватьРеестрНаСервере();
ДанныеТабДок = Результат.Документ;
// Получаем область последней строки
ПоследняяОбласть = ДанныеТабДок.Область(Результат.ПоследняяСтрока, 2, Результат.ПоследняяСтрока, 3);
// Устанавливаем текущую область и принудительно позиционируем экран
ДанныеТабДок.ТекущаяОбласть = ПоследняяОбласть;
ДанныеТабДок.Показать(ПоследняяОбласть);
КонецПроцедуры
Альтернативное эргономическое решение: Очень часто программисты пытаются решить проблему «снизу вверх», заставляя пользователя прокручивать документ. Однако с точки зрения UX (пользовательского опыта) гораздо эффективнее изменить порядок сортировки в самом запросе. Добавив в секцию упорядочивания данных конструкцию УПОРЯДОЧИТЬ ПО Дата УБЫВ (или по номеру ведомости в обратном порядке), мы добьемся того, что самые новые и актуальные ведомости будут выводиться в самом верху табличного документа. В этом случае отпадает необходимость в написании сложного кода позиционирования.
В финальной части дискуссии на форуме затронут критически важный вопрос порядка перечисления НДФЛ. Проанализируем современную методологию учета налога в 1С:ЗУП 3.1:
Отражение удержанного НДФЛ в бухучете. Именно на основании этих сведений в бухгалтерской программе формируются уведомления по ЕНП для отправки в налоговую инспекцию.