Какое количество строк в документе 1с можно
Что делать, если строк в документе больше 99’999?
Сам расчет – это, свернутая таблица по материалам. И понятно, что в итоге мы имеем ну 1000-2000 разных материалов для выполнения работ. Но, эти пару тысяч материалов собираются путем агрегирования данных из нескольких сотен (и более) смет, т.е. нескольких тысяч сметных позиций, а также вложенных в них ресурсов.
Расчет выполняется в документе, поскольку результат должен быть сохранен, для дальнейшей отправки в обработку, тендер и т.д.
Для понимания пользователя, что расчет выполнен верно, требуется реализовать ряд возможностей:
- из формы документа, при нажатии на свернутой позиции материалов, вывести данные: Смета — Позиция / Ресурс – Количество;
- печать утвержденной формы расшифровки к данной материальной ведомости;
- при объединении, перемещении и других операциях со строками все расшифровки должны переходить к новым строкам владельцам и т.д.
Табличная часть и 99’999 строк
Собственно, с самого начала понятно, что сводную таблицу материалов храним в табличной части документа, поскольку она будет отображаться в момент открытия. И лучше для этого использовать штатные механизмы. Но, вот расшифровку сбора данных, с самого начала не было никакого желания хранить в табличной части. Да и на первом же эксперименте, на примере не самой большой материальной ведомости, мы поймали данное ограничение.
В результате был придуман обходной путь:
- регистр сведений, не подчиненный регистратору (сбор выполняется редко, при каждой перезаписи документа нет нужды перезаписывать регистр) с ведущим измерением ДокументСсылка.МатериальнаяВедомость (имя документа не важно);
- на форме при создании на сервере записываем пустое значение во временное хранилище с указанием уникального идентификатора формы:
- таким образом, получили постоянный адрес для хранения данных;
- гарантировали жизнь данного адреса, до момента закрытия формы.
- Маленькая деталь: чтение данных не обязательно делать при открытии, она может быть реализована порциями, согласно отбору, полученному на основании запроса пользователя.
Таким образом, кроме того, чтобы мы обеспечили хранение и чтение данных, мы к тому же, не помещаем их в реквизит формы, в конечном итоге облегчая "вес пакета данных формы" при обмене между клиентом и сервером. Хотя, мы нагружаем сервер, но кто его жалеет, да? Принимая во внимание, что с данным документом работу выполняет крайне ограниченный круг лиц, а для остальных есть отчеты и поэтому посчитали, что сервер нагрузку переживет.
Остается существенный вопрос, зачем мы храним данные расшифровки истории сбора сводной ведомости? Во-первых, периодически, в процессе формирования актов КС-2, нам необходимо выполнять чтение данных о реальной стоимости материалов согласно данной ведомости (она, к слову, подписывается с заказчиком). Наименования материалов могут меняться, строки объединяться, но в КС-2 мы должны показать информацию о сметном названии материала, позиции в данной ведомости и ценой согласованной с заказчиком (или субподрядчиком). Таким образом, регистр расшифровки выполняет не только роль хранения "истории", но и инструмента достаточно точного получения данных.
Реализация в коде
Модуль формы документа
Модуль объекта документа
Ну вот как то так.
Постскриптум
Мы понимаем, что могли бы использовать что-нибудь "стильное, модное, молодежное", внешнюю базу данных и может быть даже NoSQL. Но, у нас просто было мало времени на подумать и еще меньше времени на реализовать. Как всегда результат нужен был "здесь и вчера". Решение было создано очень быстро, запущено в работу и проходит анализ на предмет скрытых просчетов. Более того, не у всех заказчиков возможно использование сторонних БД, поэтому данный вопрос будет скорее всего повторно обсуждаться гораздо позже.
Повторюсь, решение возможно не уникальное и не лишенное недостатков. Поэтому прошу направить на путь истинный, если имеются дельные предложения.
Специальные предложения












- Скопировать ссылку
- Перейти
- Скопировать ссылку
- Перейти
(2) Динамический список умеет в дерево
99к + строк в данных формы это абсурд, как ссылка на вх или что-то ещё:
1. Отобразить их невозможно, видимая часть списка это не так много строк
2. Если есть задача отражать изменения при записи, храни изменения в данных документа
3. Изменений больше 99к? Если да — взгляни на закрытие месяца, там тоже много изменений и ни кто не складывает их в ТЧ.ПС: Твоя проблема и её решение это одна большая ошибка.
- Скопировать ссылку
- Перейти
(6) 1. Отображать всю таблицу никто не собирался. Отображается только часть, имеющая отношение к текущей строке материала, тем более в момент «запроса» пользователя.
2. Изменять их напрямую пользователь не будет, он управляет материалами, а программа связанными с ними строками «истории» сбора данных.
3. Вот поэтому в тч хранить и не стали. Это ни к чему.Опять повторюсь, я кажется дал с самого начала достаточно информации для создания альтернативной структуры хранения.
- Скопировать ссылку
- Перейти
1. Пользователь, что-то делает с материалами
2. Это что-то сохраняется в документ
3. При записи/проведении рассчитываются изменения и куда-то складываютсяИз регистра сведений удаляется документ как измерение и устанавливается периодичность по регистратору
1. Создается и записывается документ
2. Все действия пользователя сразу пишутся в РС
3. Пока документ не проведен, активность записей — Ложь- Скопировать ссылку
- Перейти
(12) вот это другое дело ;), давай обсудим.
Предложение 1 по сути есть продолжение описанного в статье. После того, как данные были собраны, они могут быть изменены, вот эти изменения будут проанализированы и в расшифровку точечно внесены изменения.
Предложение 2 в принципе предложение рабочее. Есть один нюанс, пока не нажата кнопка «Записать» обычно пользователю считают что все изменения — это «вилами на воде писано». При обрыве соединения сохранятся изменения регистра, но данные объекта документа не изменяться. Или зависнут «неактивные» позиции и их придется как то потом подчищать.
- Скопировать ссылку
- Перейти
Если бы знал бизнес процесс, я бы выбрал №1, но что бы это обсуждать нужен контекст, у меня его нет, посему про предложение 2.
Почему и про нюансы:
1. Сам факт существования объекта иб при создании можно скрыть, для этого достаточно сделать отбор по какому-то его реквизиту в списке
2. При обрыве соединения пользователь не потеряет данных, можно будет дать возможность продолжить творчество с того места где он остановился.
3. Активность как свойство записи входит в индекс и по умолчанию не попадает в срезы, очистка данных может быть не оперативной.Самое главное:
1. Мы не сталкиваемся с ограничениями при масштабировании в большую сторону.- Скопировать ссылку
- Перейти
- Скопировать ссылку
- Перейти
Вообще периодичность по регистратору и активность можно не использовать.
Документ и признак активности могут быть самостоятельными измерением, основная идея в следующем:
- Скопировать ссылку
- Перейти
Рассматривали вот такой вариант?
При создании документа генерировать новую ссылку документа и везде использовать её (при записи применять её). Соответсвенно вместо таблицы значений использовать динамический список с отбором по ссылке (реальной или сгенерированной при создании нового).PS: Увидел, что я не первый уже после отправки комметария :о)
- Скопировать ссылку
- Перейти
- Скопировать ссылку
- Перейти
(4) Именно поэтому и спросил рассматривали такой вариант или нет. Да, именно в вашем случае, когда может быть загружен большой объём и после этого велика вероятность отказа от записи, более логично времено хранить на клиенте. Но тогда мы увеличиваем требования на клиентскую часть (объём памяти и частично процессор на обработку) вместо того чтобы этим занимался сервер (вообще файл передать на сервер для загрузки). В случае с динамическим списком как минимум отпадает необходимость отработки частичного чтения. Возможность «отката» тоже реализовать на вскидку в голове пара способов крутится.
У каждого решения есть своя сфера применимости с плюсами и минусами.
ПС: При очистке регистра не нужно его читать. Можно сразу записывать набор после установки отбора.
ПС2: Не надо так резко воспринимать комметарии, этим только вызываете общий негатив.
- Скопировать ссылку
- Перейти
(13) маленькая поправка, на клиент весь набор собранных данных (все эти много строк) не передаются, они во временном хранилище остаются. У клиента есть адрес хранилища, и при необходимости через вызов сервера, он может получить ровно ту часть строк, которые в текущий момент необходимо отобразить.
В общем получается такая схема:
— если нажата кнопка «Заполнить», то считанные данные помещаются во временное хранилище. Клиент получает ответ что все собрано и таблицу только уникальных позиций материалов, а вся расшифровка остается на сервере. На клиенте никоим образом отражения она не находит.
— после записи документа,при повторном открытии, мы не сразу заполняем все данные расшифровки. Возможно пользователю она вообще не понадобится в процессе работы. Когда пользователь запрашивает необходимость расшифровки, именно эта часть считывается из регистра и дополняется в таблицу хранилища. Таким образом, мы его наполняем постепенно.Во всех случаях на клиенте остается только адрес хранилища и видимая часть уникального набора материалов.
Пс. да, это я уже увидел. Не знаю откуда такая привычка писать. Никогда не задумывался. Спасибо за указание ошибки.
Пс2. видимо спал вчера мало, прошу прощения у всех
- Скопировать ссылку
- Перейти
- Скопировать ссылку
- Перейти
- Скопировать ссылку
- Перейти
- Скопировать ссылку
- Перейти
- Скопировать ссылку
- Перейти
- Скопировать ссылку
- Перейти
Идея хорошая. Возможно будут полезны замечания.
1) Обернув код записи набора записей в Попытку-Исключение в уже открытой транзакции записи документа получили возможность возникновения невосстановимой ошибки во «вложенной» транзакции. Комбинация адекватного сообщения пользователю, выдаваемого методом ОбщегоНазначенияКлиентСервер.СообщитьПользователю и пугающего диалога с «В данной транзакции уже происходили ошибки» — это не лучшее решение. Нужно выбрасывать возникшее исключение выше через ВызватьИсключение а не просто сообщать пользователю. Тогда этот метод записи данных можно использовать и в серверных алгоритмах вне интерактивного взаимодействия с пользователем.
2) Перед заполнением набора записей в методе ЗаписатьДанныеВременногоХранилища блокировка данных не нужна. Вы же не выполняете предварительного чтения чтобы новые данные писались на основе старых. И вы же не ставите такую блокировку в методе ОчиститьРегистрСведенийХранениеДанныхДокумента, где точно такой же код за исключением того, что цикл заполнения набора записей заменен на метод чтения из БД.
3) Зачем в методе ОчиститьРегистрСведенийХранениеДанныхДокумента вообще чтение из БД?
НаборЗаписей.Прочитать();
НаборЗаписей.Очистить();
НаборЗаписей.Записать(Истина);Вроде бы как в регистре большое количество данных. Зачем их читать на сервер 1С чтобы потом сразу очистить эти данные и снова записать? Здесь ничего кроме установки неявной разделяемой управляемой блокировки не произойдет. И думаю что метод чтения из БД кучи данных вызывается вовсе не с целью установить неявную блокировку. Таким образом этот вызов является ошибкой.
4) Регистр перезаписывается целиком для документа. Если нам нужно добавить данные к уже существующим или удалить только часть данных, то алгоритм придется менять, и в методе ЗаписатьДанныеВременногоХранилища придется все-таки добавлять предварительное чтение всего объема данных по документу из регистра. Чтобы затем поменять только часть записей. Это очень не оптимально, учитывая исходные условия задачи : большой объем данных по документу.
Если обеспечить идентификацию строк в документе в свернутой таблицы материалов (например добавить автозаполняемый реквизит с типом УникальныйИдентификатор или инкрементальный числовой идентификатор), то можно было бы сделать вторым измерением регистра идентификатор строки. В этом случае получили бы больше возможностей по независимому изменению расшифровки каждой строки.
- Скопировать ссылку
- Перейти
(11) спасибо за замечания все по делу. Действительно полезно.
1. Да, вы правы. Спасибо за подсказку, изменения будут внесены.
2. Использовать блокировку стало какой-то привычкой, причем видимо мозг уже отключается о причинах, зачем это делается. Так же согласен.
3. Чтение тоже ни к чему, согласен также.
4. Вот тут маленькая поправка. Выложил не всю информацию, сознательно ее упростив. Ваше замечание верно, и оно реализовано.
Регистр имеет структуру: Документ / Ключ строки / Смета / Ключ позиции сметы
Т.е. при необходимости можно перезаписать все данные, а можно по отдельным ключам, которые были изменены. Поскольку механизм взаимодействия пользователей сейчас в работе, процедура записи не была пока изменена. Но в будущем, когда из формы будут приходить данные об изменениях только отдельных групп строк, тогда будет реализована и запись части набора, без затрагивания остальных.- Скопировать ссылку
- Перейти
(14)
Если реализован регистр с измерениями Документ / Ключ строки / Смета / Ключ позиции сметы и данные действительно перезаписываются не целиком по измерению Документ , а по сочетанию измерений, то при запись данных в регистр сведений в методе ЗаписатьДанныеВременногоХранилища скорее всего идет внутри цикла, перебирающего комбинации измерений.В таком случае управляемая блокировка до начала записи действительно нужна. И тогда пункт 2 из замечаний надо вычеркнуть. Иначе параллельная транзакция читая данные в целом по документу может получить несогласованный набор данных, состоящий из части «новых» расшифровок строк и части «старых» расшифровок. Вообще тут думать надо исходя из того, возможно ли такое чтение в других сеансах.
Функция СтрЧислоСтрок()
Функция СтрЧислоСтрок() Подсчитывает количество строк в многострочной строке. В качестве разделителя в многострочной строке используются символы перевода строк (программно: Символы.ПС ). При этом если после последнего символа перевода строки нет значащих символов, то он игнорируется.
Доступность
Тонкий клиент, веб-клиент, мобильный клиент, сервер, толстый клиент, внешнее соединение, мобильное приложение(клиент), мобильное приложение(сервер).
Как очистить табличную часть документа в 1С
Как я уже говорил в предыдущих статьях, обрабатывать табличную часть какого либо объекта 1С необходимо уметь каждому, даже самому начинающему 1С — нику. Так как большинство доработок (как показывает практика) касается табличных частей. Кому-то необходимо пересчитывать цены с учетом скидки, кому-то удалять или добавлять строки, реквизиты, заполнять табличную часть подбором и т.д. Обо всем рассказать практически не возможно так как каждое решение индивидуально, а вот об общих принципах попробовать можно, я уже написал несколько статей касающихся это теме, сегодня же расскажу как можно полностью очистить табличную части какого либо объекта.
Удаление всех строк из ТЧ документа
И так в некоторых документах табличная часть может быть очень большой, содержать большое количество строк, удалить их можно вручную, выделив все строки кликнуть ПКМ мыши и нажать удалить, но лучше добавить на форму кнопку, после нажатия на которую все строки ТЧ удалятся. Это намного удобней и быстрей.
Практиковаться лучше на новом документе в котором нет чужого кода, это позволяет быстро во всем разобраться. Я возьму документ из предыдущих статей, у него есть табличная часть «Товары».

Первым делам создаем команду (кнопку) и добавляем её на форму.

Далее в процедуре пишем вот такой код.

Сохраняем и проверяем что получилось.

После нажатия на кнопку «Очистит ТЧ» она должна очиститься.

При условии что вы все сделали правильно, хотя запутаться тут просто не возможно.
Как посчитать количество строк в табличной части?
Необходимо настроить два числовых реквизита — реквизит шапки, для расчета количества строк, и служебный реквизит табличной части, со значением по умолчанию, равным единице:

Далее настраивается выражение, возвращающее итог по служебному реквизиту табличной части , и оно присваивается реквизиту шапки:

Поскольку значение служебного реквизита в каждой строке равно единице, итог равен количеству строк в табличной части:

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

Например, может возникать ситуация, что мы редактируем какое-нибудь поле текущей строки таблицы на форме, и нам нужно, чтобы было пересчитано другое поле (или несколько полей) этой текущей строки. Например, мы изменяем цену (или количество) нашей табличной части, и необходимо, чтобы сумма автоматически была пересчитана.
Для решения данной задачи нужно воспользоваться свойством ТекущиеДанные элемента с типом ТаблицаФормы, который соответствует нужной табличной части. Свойство ТекущиеДанные возвращает значение полей текущей строки.

Для того, чтобы отработать изменение текущего поля цены, создадим обработчик события ПриИзменении этого поля.

В этом обработчике напишем код, который будет пересчитывать значения полей текущей строки табличной части.
Ещё пример: я создал команду, которая должна увеличивать количество в текущий строке табличной части в два раза и пересчитывать сумму. Эта команда размещена в командной панели таблицы и имеет следующий код:
Теперь доработаем этот пример: после увеличения текущей строки будем сдвигать текущую строку на строку вниз. Для этого допишем предыдущий код:
В этом коде мы получаем идентификатор текущий строки при помощи свойства таблицы управляемой формы ТекущаяСтрока, и если мы не выходим за приделы таблицы, то сдвигаем нашу текущую строку на один шаг вниз.
Также при помощи текущей строки можно находить аналогичную строку в соответствующей табличной части основного реквизита формы Объект, которую также можно изменять (строка на форме тоже изменится автоматически). Мы ранее сделали пересчет суммы при изменении цены, теперь сделаем пересчет суммы при изменении количества, но напрямую через реквизит Объект.
Как в 1С выделить несколько строк
При работе в 1С бывает нужно выполнить действия над несколькими объектами сразу. Например, перепровести, отменить проведение документов, пометить на удаление элементы и так далее. Для этого можно использовать обработку «Групповое изменение реквизитов», но это затратно по времени.
Есть другой, более простой способ выполнения таких задач — выделение нескольких строк в самих объектах. Рассмотрим несколько примеров на программе 1С:Бухгалтерия предприятия.
Как выделить сразу все документы
Первый пример — когда нужно выделить сразу все документы. Откроем список документов «Реализация (акт, накладная)».

Для выделения всех строк нажмем комбинацию клавиш CTRL+A на клавиатуре. Все строки будут желтого цвета.

Теперь можем выполнить массовое изменение. Для этого нажмем правой кнопкой мыши в списке документов, либо кнопку «Еще». Затем выбираем нужное действие, например, «Провести».

Как выделить несколько документов по порядку
Допустим, нам нужно выделить документы за январь 2016 года. CTRL+A здесь уже не подойдет, так как будут включены и другие периоды.

Получите понятные самоучители по 1С бесплатно:
- Встаем курсором на начало выделяемой строки, в данном случае это строка с датой 12.01.2016.
- Зажимаем клавишу SHIFT.
- Щелкаем левой кнопкой мыши по строке, в которой должно закончиться выделение. В данном случае это строка с датой 31.01.2016. При этом клавишу SHIFT не отпускаем.
Получим такой результат.

Выделились только нужные нам строки.
Как выборочно выделить документы
Допустим, нам нужно выделить несколько строк, которые идут не по порядку.

- Зажимаем клавишу CTRL.
- Не отпуская клавишу щелкаем левой кнопкой мыши поочередно на нужных строках.
Получим такой результат.

При этом, если случайно зацепили лишнюю строку, не нужно начинать сначала. Удерживая клавишу CTRL, просто щелкните по этой строке еще раз, ее выделение отменится.
Таким образом, мы рассмотрели, как выделить несколько строк в 1С. Эти способы можно применять практически в любых списках документов, справочников, а также отчетах.