Программисту 1С: Максимальное количество строк табличной части, как обойти ограничение

Одним из существующих ограничений платформы 1С 8.3 является ограничение на количество строк табличной части.
Табличная часть документа не может содержать более 99 999 строк. Точнее будет сказать, что нельзя сохранить в базе данных более 99 999 строк табличной части.
Почему так сказать будет точнее? Потому что во время интерактивной работы с документом в табличной части может быть сколько угодно строк, но вот сохранить их все в базе данных в виде объекта типа ТабличнаяЧасть будет нельзя.

Чтобы обойти это ограничение используют следующий прием: данные, которые должны быть в табличной части, в момент сохранения документа в базе данных, помещают в регистр сведений (непериодический, с независимым режимом записи), а после записи снова извлекают эти данные и помещают обратно в табличную часть:

п.1. Перед записью документа в этот регистр сведений помещаются строки из ТЧ, а ТЧ очищается. Для этого используется обработчик события ПередЗаписью, размещенный в модуле объекта. (Примечание. Событие ПередЗаписью прикладного объекта отличается от события ПередЗаписью формы, связанной с этим прикладным объектом. Обработчик события в модуле формы вызывается при интерактивной записи, а обработчик в модуле объекта при любом способе записи элемента в базу данных.)

п.2. Сразу после записи документа эта ТЧ снова заполняется данными из регистра. Для этого в модуле формы размещают обработчик события ПослеЗаписиНаСервере

п.3. Предусматривается необходимость очистки регистра сведений от записей в случае пометки его на удаление. Так как регистр сведений имеет независимый режим записи, регистр не подчинен регистратору, то при пометке на удаление документа записи из регистра сами удалиться не могут. Поэтому им придется «помочь». В противном случае мы не сможем удалить документ — обработка «Удаление помеченных объектов» будет находить ссылки на удаляемый документ и отказываться его удалить.

Пример такого кода.

// Обработчик события "Перед записью" (обработчик события назначается в форме документа, процедура располагается в модуле объекта), в табличную часть которого не влезают данные 
// РегистрДанныхБольшойТЧ - регистр сведений, созданный специально для хранения данных именно данной табличной части именно данного документа. Среди измерений этого регистра первым измерением должен быть Документ - ссылка на документ, табличную часть которого мы в регистр выгружаем
// БольшаяТЧДокумента - некая большая табличная часть нашего документа
// "Сотрудник,Подразделение,..." - сворачиваемые поля 
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
	// п.1
	рег = РегистрыСведений.РегистрДанныхБольшойТЧ.СоздатьНаборЗаписей();
	рег.Отбор.Документ.Установить(ТекСсылка,Истина);
	рег.Записать(Истина);
	
	// Перед выгрузкой в регистр можно выгрузить в таблицу значений и свернуть ее (если требуется):
	ТЗ = БольшаяТЧДокумента.Выгрузить();
	ТЗ.Свернуть("Сотрудник,Подразделение,...","Сумма1,Сумма2,...");
	
	// заполняем регистр строками свернутой ТЗ:
	Для каждого стр Из ТЗ Цикл
		
		стрРег = рег.Добавить();
		ЗаполнитьЗначенияСвойств(стрРег, стр);
		// устанавливаем ссылку на текущий документ для каждой строки регистра:
		стрРег.Документ = ТекСсылка;
		
	КонецЦикла;
	
	// записываем в регистр добавленные записи регистра
	рег.Записать(Истина);
	
	// очищаем табличную часть от записей
	БольшаяТЧДокумента.Очистить();
	
	
	// п.3
	Если ПометкаУдаления Тогда // - очищаем "движения" в регистрах
		
		УстановитьПривилегированныйРежим(Истина);
		
		рег = РегистрыСведений.РегистрДанныхБольшойТЧ.СоздатьНаборЗаписей();
		рег.Отбор.Документ.Установить(Ссылка,Истина);
		рег.Записать(Истина);
		
		УстановитьПривилегированныйРежим(Ложь);
		
	КонецЕсли;
// ...
КонецПроцедуры

// п.2

&НаСервере
Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
	
	Если НЕ Объект.Ссылка.Пустая() Тогда
		
		Запрос = Новый Запрос;
		Запрос.Текст =
		"ВЫБРАТЬ
		|	РегистрДанныхБольшойТЧ.Документ,
		|	РегистрДанныхБольшойТЧ.Сотрудник,
		|	РегистрДанныхБольшойТЧ.Подразделение,
		|	...,
		|	РегистрДанныхБольшойТЧ.Сумма1,
		|	РегистрДанныхБольшойТЧ.Сумма2,
		|	...
		|ИЗ
		|	РегистрСведений.РегистрДанныхБольшойТЧ КАК РегистрДанныхБольшойТЧ
		|ГДЕ
		|	РегистрДанныхБольшойТЧ.Документ = &Документ";
		Запрос.УстановитьПараметр("Документ",Объект.Ссылка);
		
		Объект.БольшаяТЧДокумента.Загрузить(Запрос.Выполнить().Выгрузить());
		
	КонецЕсли;
	
КонецПроцедуры

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.