31 января 2021 г.

1С Программно добавить колонку в макет

Заголовок конечно неправильный, но именно так я начал поиск ответа на вопрос - как в добавить дополнительную колонку в счет-фактуре не изменяя макет?



Скажу так - геморрой еще тот, а ответ на вопрос - "ВставитьОбласть()"

У ТабличногоДокумента есть метод ВставитьОбласть(), по умолчанию он замещает область, но может и не замещать, это дает нам возможность "программно вставлять колонки в макеты".

Понятно что не в макет, а уже в табличный документ.

Сразу оговорюсь, весь функционал действителен для платформы версии 8.3.17.1851, остальные я не проверял.

Начав вносить изменения в типовую конфигурацию (БП 3.0) при помощи расширений, для сохранения поддержки, я наткнулся на новую (аж 2019 год) аннотацию ИзменениеИКонтроль, она открыла передо мной невероятные возможности. Например: теперь я могу в момент сборки ТабличногоДокумента вносить изменения, или еще в запросе данных для ТД внести свои коррективы. И я решил сначала просто добавлять строки при необходимости в момент вывода, т.е. т.о. отказаться от своего макета (они в расширениях ведут себя странно). Получилось.

Потом я пошел еще дальше, заказчик попросил дополнительную колонку в счет фактуре и до моего открытия я ему говорил "а-та-та, все поедет" и предлагал артикул (то что он хотел) выводить вместе с наименованием товара. Я решил потратить время для проверки возможности и пришел к успеху.

Проблемы с которыми я столкнулся:

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


Обращаем внимание на то, что высота области в данном случае 3 строчки, и у них разное форматирование. Сначала находим код отвечающий за вывод области "ЗаголовокТаблицы" - ВывестиСчетФактуруВТабличныйДокумент:

  
Процедура ВывестиСчетФактуруВТабличныйДокумент(ТабДокумент, Макет, ВыборкаСФ, ЭтоУниверсальныйПередаточныйДокумент)
...
	// Вывод заголовка таблицы

	ОбластьМакета = Макет.ПолучитьОбласть("ЗаголовокТаблицы");
	ТабДокумент.Вывести(ОбластьМакета);

#Вставка
	//ВыборкаСФ.ДокументыОснования[0].ПечататьАртикул - в моем случае галка на форме разрешающая печать артикула
	//ЭтоУниверсальныйПередаточныйДокумент - данный макет в УПД съезжает, требуется корректировка
	Если ВыборкаСФ.ДокументыОснования[0].ПечататьАртикул  и НЕ ЭтоУниверсальныйПередаточныйДокумент Тогда
		ДобавитьКолонкуВЗаголовок(ТабДокумент); //т.к. два раза повторяется вывод одного и того же кода, я вывел его в отдельную процедуру
	КонецЕсли;
#КонецВставки
...
КонецПроцедуры
Процедура ДобавитьКолонкуВЗаголовок(ТабДокумент)
	//определяем высоту области
	ТабНиз=ТабДокумент.Области.ЗаголовокТаблицы.Низ;
	ТабВерх=ТабДокумент.Области.ЗаголовокТаблицы.Верх;
	//исходная область
	ТабОблСтарая="R"+ТабВерх+"C2"+":"+"R"+ТабНиз+"C2";
	//определяем адрес подобластей в будущей вставке, только из-за двух разных содержимых
	ТабОблНоваяШапка="R"+ТабВерх+"C3"+":"+"R"+(ТабНиз-1)+"C3";
	ТабОблНоваяШапкаНомер="R"+(ТабНиз-1)+"C3"+":"+"R"+ТабНиз+"C3";
	//вставляем область, она смещает все вправо
	ТабДокумент.ВставитьОбласть(ТабДокумент.Область(ТабОблСтарая),,ТипСмещенияТабличногоДокумента.ПоГоризонтали);
	Линия = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная,1);
    
	//объединияем ячейки первой и второй строки, обводим, вставляем текст, определяем положение тектс
	ТабДокумент.Область(ТабОблНоваяШапка).Объединить();
	ТабДокумент.Область(ТабОблНоваяШапка).Текст="Артикул";
	ТабДокумент.Область(ТабОблНоваяШапка).Обвести(Линия,Линия,Линия,Линия);
	ТабДокумент.Область(ТабОблНоваяШапка).ГоризонтальноеПоложение=ГоризонтальноеПоложение.Лево;
    
	//обрабатываем третью строку по вкусу
	ТабДокумент.Область(ТабОблНоваяШапкаНомер).Обвести(Линия,Линия,Линия,Линия);
	ТабДокумент.Область(ТабОблНоваяШапкаНомер).Текст="";
КонецПроцедуры

Продолжаем также с остальными областями, дальше легче. Все вроде прекрасно, но если посмотреть вывод, то он будет кривоват из-за ширины столбцов, которая изменилась. Если поставить такие же, то таблица не будет вмещаться в оригинальную область печати. Решение простое, такое же как и при создании своего макета - сохранить оригинальные размеры всех столбцов и выборочно сузить имеющиеся до приемлемых габаритов. Сначала сохранил оригинальные размеры (сохраняем после вывода "ЗаголовокТаблицы", но до наших манипуляций):

  
Процедура ВывестиСчетФактуруВТабличныйДокумент(ТабДокумент, Макет, ВыборкаСФ, ЭтоУниверсальныйПередаточныйДокумент)
...
	// Вывод заголовка таблицы

	ОбластьМакета = Макет.ПолучитьОбласть("ЗаголовокТаблицы");
	ТабДокумент.Вывести(ОбластьМакета);

#Вставка
	//ВыборкаСФ.ДокументыОснования[0].ПечататьАртикул - в моем случае галка на форме разрешающая печать артикула
	//ЭтоУниверсальныйПередаточныйДокумент - данный макет в УПД съезжает, требуется корректировка
	Если ВыборкаСФ.ДокументыОснования[0].ПечататьАртикул  и НЕ ЭтоУниверсальныйПередаточныйДокумент Тогда
		МассивШириныКолонок=Новый Массив;
		МассивШириныКолонок.Очистить();
		ВосстановитьШиринуКолонок(ТабДокумент,Ложь,МассивШириныКолонок); //опять же создал Процедуру, она выполняет как сохранение, так и восстановление
        ДобавитьКолонкуВЗаголовок(ТабДокумент); //т.к. два раза повторяется вывод одного и того же кода, я вывел его в отдельную процедуру
	КонецЕсли;
#КонецВставки
...
#Вставка
	//вызываем восстановление размеров в самом конце, чтобы наша очередная вставка не изменила размеры
	Если ВыборкаСФ.ДокументыОснования[0].ПечататьАртикул  и НЕ ЭтоУниверсальныйПередаточныйДокумент Тогда
		ВосстановитьШиринуКолонок(ТабДокумент,Истина,МассивШириныКолонок);
	КонецЕсли;
#КонецВставки
КонецПроцедуры
Процедура ВосстановитьШиринуКолонок(ТабДокумент,Восстановить=Ложь,МассивШириныКолонок)
	КоличествоКолонок=ТабДокумент.ШиринаТаблицы;
	ТабНиз=ТабДокумент.Области.ЗаголовокТаблицы.Низ;
	ТабВерх=ТабДокумент.Области.ЗаголовокТаблицы.Верх;
	Если НЕ Восстановить Тогда
		Для Счетчик = 3 По КоличествоКолонок Цикл
			МассивШириныКолонок.Добавить(ТабДокумент.Область("R"+ТабНиз+"C"+Счетчик+":"+"R"+ТабНиз+"C"+Счетчик).ШиринаКолонки);
		КонецЦикла;					
	Иначе
		Для Счетчик = 4 По КоличествоКолонок Цикл
			//ужимаем чтобы влезла по максимуму
			УжатьПунктов=0;	
			Если Счетчик = 5 или Счетчик = 14 Тогда
				УжатьПунктов=2;
			ИначеЕсли Счетчик =11 Тогда
				УжатьПунктов=3;
			ИначеЕсли Счетчик = 16 или Счетчик = 15 Тогда
				УжатьПунктов=1;
			КонецЕсли;
			ТабДокумент.Область("R"+ТабНиз+"C"+(Счетчик)+":"+"R"+ТабНиз+"C"+(Счетчик)+"").ШиринаКолонки=МассивШириныКолонок[Счетчик-4]-УжатьПунктов;
		КонецЦикла;
	КонецЕсли;
КонецПроцедуры

Во второй части ВосстановитьШиринуКолонок используется переменная УжатьПунктов, опытным путем подобрал ширину разных колонок, освободив 9 пунктов для моего столбца.

Ну и как будто бы всё

Комментариев нет:

Отправить комментарий