Однажды у коллег возникла проблема. На первый взгляд, пустяк, да и только. Всего-то поменять счет дебета и одно субконто в отдельно взятом документе "Операция (бухгалтерская)". Это в конфигурации "Бухгалтерия государственного учреждения 2.0".
Задача осложнялась тем, что поменять надо было во всех строчках табличной части. Во всех восьмиста. Причем документ был сделан без использования типовых операций.
Разумеется, каждый, к кому обращались за советом, тут же принимался искать групповое изменение реквизитов. Ну, и я тоже. Понятно ведь, что коллеги слегка затупили, но я-то самый умный. Обычно я туплю по другим вопросам, а с этим – ща разберемся.
Ага, разобрались… В контекстном меню даже пункта такого нет. Захожу через Администрирование – обработка не видит табличную часть. Загружаю внешнюю обработку – и та не видит. Как вы догадываетесь, то же самое наблюдали все остальные.
И вот тут до нас дошло, что арифметика совсем не в нашу пользу. Проблемных строчек по-прежнему восемьсот, а подходящих инструментов – ни одного.
Секрет, в общем-то, прост – нет там никакой табличной части. Вместо нее документ показывает регистр бухгалтерии ЖурналПроводокЕПСБУ. А чтобы мало не показалось, регистр, в свою очередь, подсовывает виртуальную таблицу ДвиженияССубконто. А иначе никаких субконто мы вообще не увидим.
Все желающие могут полюбоваться на это безобразие в конструкторе запросов. Уверен, вам понравится. Если хотите увидеть субконто, правильный подход выглядит примерно так:
ВЫБРАТЬ
Таб.НомерСтроки КАК НомерСтроки,
Таб.СчетДт КАК СчетДт,
Таб.СубконтоДт1 КАК СубконтоДт1,
Таб.СубконтоДт2 КАК СубконтоДт2,
Таб.СубконтоДт3 КАК СубконтоДт3,
Таб.СчетКт КАК СчетКт,
Таб.СубконтоКт1 КАК СубконтоКт1,
Таб.СубконтоКт2 КАК СубконтоКт2,
Таб.СубконтоКт3 КАК СубконтоКт3
ИЗ
РегистрБухгалтерии.ЖурналПроводокЕПСБУ.ДвиженияССубконто КАК Таб
ГДЕ
Таб.Регистратор.Ссылка = &Ссылка
где в качестве параметра Ссылка может выступать чуть ли не половина документов, существующих в конфигурации. Например, та же "Операция (бухгалтерская)".
Ну так вот, получается, что пока документ не откроет свою форму, он даже сам не знает, как много интересного в нем написано. А заодно и всякие полезные обработки ничего об этом не знают, они ведь тоже на форму не смотрят.
В общем-то, на этом месте можно было развести руками. Мол, "ну, не шмогла". Однако ж, восемьсот строчек смотрели на меня с ухмылкой и укоризной: "Какой ты, нахрен, программист после этого? Восемьсот раз не можешь сделать одно и то же. Разве не этому тебя учили на втором занятии по Бейсику?"
Так-то оно так, вот только в Бейсике не было регистра бухгалтерии. Особенно когда я его учил.
К счастью, проблема возникла в пятницу. На улице мороз, пандемия, все ходят в масках и меня заставляют. Короче, пока вы там все в масках свежим воздухом дышите, я лучше дома посижу, полезный инструмент склепаю. Пусть это будет мой личный хакатон. Глядишь, еще и статью напишу.
Собственно, вот и статья, а в конце – то, что получилось. Комплект состоит из расширения и внешней обработки. Расширение готовит почву для обработки, но без нее никто не отредактирует документы шаловливыми ручками. Поэтому и не стал делать все в одной компоненте. Вы можете поступать, как считаете нужным.
У расширения задан режим совместимости с 8.3.12. Просто дома я работаю на учебной версии платформы 8.3.13.1644, поэтому пришлось развернуть демобазу БГУ 2.0 примерно полугодовой давности. Когда притащил готовый результат на работу, более свежая платформа сама предложила поменять совместимость на 8.3.14.
Поскольку обратный переход не предусмотрен, здесь прилагается домашний вариант, то есть совместимый с 8.3.12.
Расширение здесь нужно только ради одного – выполнить действия, предусмотренные при изменении полей таблицы. А для этого нужны экспортные процедуры, живущие в модуле формы документа. Я даже не стал переназначать обработчики. Просто скопировал их в расширение и слегка поправил, как мне надо. То есть у меня это и не обработчики, и не их расширения, хотя очень похожи.
Догадываюсь, что такой подход вызовет критику, но для эпизодического применения и так сойдет. Впрочем, критика ожидается и принимается, как и полезные советы.
Кстати, в связи с расширением хотелось бы передать отдельный привет разработчикам БГУ. Ну, не считая тех приветов, которые мы регулярно посылаем в рабочее время. Вслух и мысленно.
Вот, к примеру, смотрю я модуль формы документа, и вроде бы, все хорошо. Обработчики события ПриИзменении у полей таблицы очень приятно выглядят. Например, у полей СчетДт / СчетКт они смотрят на своей форме выделенную строку, а потом вызывают из общего модуля процедуру СубконтоПриИзменении() и передают ей только поле таблицы. Отлично, поправлю их так, чтобы смотрели в мои строчки, и готово.
А для всех шести полей Субконто... обработчики вообще одинаковые и удивительно лаконичные:
&НаКлиенте
Процедура ДвиженияЖурналПроводокСубконтоДт1ПриИзменении(Элемент)
БухгалтерскиеОперацииКлиент.СубконтоПриИзменении(Элемент,,, Истина);
КонецПроцедуры
Все та же СубконтоПриИзменении() с полем таблицы. Вообще ничего делать не надо.
Оказалось, что надо. Мне как-то в голову не приходило, что где-то дальше, за пределами формы, заново прочитывается строка, выделенная пользователем. Вот как раз в процедуре общего модуля то самое и происходит. Прям так, посреди процедуры:
Общий модуль БухгалтерскиеОперацииКлиент
Процедура СубконтоПриИзменении(Элемент, Знач ПрефиксСубконтоДанных = "",
Знач СтруктураИменСубконто = Неопределено, УстанавливатьКЭК = Ложь) Экспорт
Таблица = БухгалтерскиеОперацииКлиентСервер.ПолучитьРодителяПоТипуЭлемента(Элемент, Тип("ТаблицаФормы"));
Форма = БухгалтерскиеОперацииКлиентСервер.ПолучитьРодителяПоТипуЭлемента(Элемент, Тип("УправляемаяФорма"));
…
ТекущиеДанные = Таблица.ТекущиеДанные;
…
КонецПроцедуры
Красота. Форму и таблицу узнают по переданному параметру, а текущую строку – просто глядя на форму. И ведь нет у процедуры ни одного параметра, чтобы передать строку при вызове. Так что и в расширении через параметры не передашь. Ну вот зачем так делать?
Можете не объяснять, я догадываюсь. 1С не всегда думает обо мне. Пришлось в расширении создать реквизит формы и туда класть строку, а заодно притащить процедуру общего модуля и слегка поправить. Как раз там, посреди процедуры.
Все грабли, по которым я прошелся на выходных, перечислять не буду. Главное, что инструмент готов и решает поставленную задачу. Теперь мне не стыдно смотреть на восемьсот вредных строчек. Пусть боятся.
Дополнение. О правильном подходе
Когда статья была опубликована, в комментариях мне подсказали, как надо было правильно подойти к задаче. Конечно же, я решил сделать второй вариант обработки, который обращается напрямую к регистру и поэтому не нуждается в обработчиках событий формы, а значит, и в расширении. Ведь так гораздо удобнее.
Поскольку меня больше всего беспокоили сложности с субконто, при тестировании я менял значения именно в этих полях. Ну, и в итоге добился безупречной работы новой утилиты. По граблям, конечно, и в этот раз прошелся, куда ж без них.
Но еще когда правильный подход обсуждался в комментариях, у меня было подозрение, что со счетами нельзя так вольно обращаться, как с другими реквизитами. Стоило только начать исправлять счета, и подозрения тут же подтвердились.
Здесь необходимо отметить принципиальную разницу в подходах к задаче. В первом варианте (с расширением) исправления делаются на форме документа, но в базу не вносятся, пока пользователь не нажмет "Записать и закрыть". При этом сначала можно исправить одни поля, потом другие и так далее, а потом уже сохранить все изменения сразу. А главное, пользователь видит реакцию формы на исправления и таким образом получает подсказки.
Во втором варианте исправления сразу вносятся в базу. Но какие-то поля могут быть исправлены сами по себе, а какие-то – лишь в связке с другими полями. Например, при попытке исправить только счет, скорее всего, будет получен отказ, потому что окажутся неправильно заполненными субконто и еще что-нибудь.
Значит, надо предусмотреть изменение группы взаимосвязанных полей, а это делает форму обработки громоздкой, а всю разработку выводит из категории слепленных на коленке для разового применения.
Получается, что, избегая трудностей с регистром, я реализовал в первом варианте решение, более корректное с точки зрения пользователя: сначала все поправим, посмотрим, проверим, и только потом сохраним.
К тому же, в первом варианте любое исправление происходит моментально, буквально на глазах у пользователя. Продолжительная операция сохранения документа вынесена за скобки и не задерживает работу. Ну, и до последнего момента пользователь может передумать и отказаться от изменений.
Второй вариант опубликован для желающих посмотреть на реализацию замечаний из комментариев. Но форма обработки по-прежнему предполагает исправление только одного поля, о чем сказано в предупреждающей надписи.