Копирование набора записей регистра и строк табличной части в 1С

· 9 мин

Содержание

Набор записей в 1С — это все записи регистра, которые относятся к одному набору значений измерений и регистратору. Скопировать его можно тремя путями: кнопкой «Копировать» в форме списка, через выгрузку в таблицу значений в коде или переносом через файл и обработку загрузки данных. Какой из них выбрать, зависит от того, нужна ли одна запись, десять или десять тысяч, и копируете вы внутри базы или в другую.

Слово «набор» путают с табличной частью документа. Это разные вещи: у табличной части есть владелец-документ, у набора регистра — отбор по измерениям или по регистратору. Способы похожи, но подводные камни разные. Ниже — оба случая.

Что именно вы копируете: регистр или табличную часть

Сначала определите объект. От этого зависит всё остальное.

ОбъектКак устроенЧто мешает копированию
Независимый регистр сведенийЗаписи живут сами по себе, ключ — измерения (и период)Дубль по ключу: запись с теми же измерениями заменит существующую
Подчинённый регистру регистратору (сведений, накопления, бухгалтерии)Записи привязаны к документу-регистраторуНельзя «просто добавить» запись: её создаёт проведение документа
Табличная часть документа или справочникаСтроки внутри объектаНужно сохранить объект, чтобы строки попали в базу

Если регистр подчинён регистратору, правильное копирование — это копирование самого документа и его проведение. Движения сформируются заново сами. Руками правят такие наборы только программно и только когда понятно, зачем.

Прямая запись в регистры накопления и бухгалтерии в обход документа ломает связь «документ — движения». При следующем перепроведении ваши правки пропадут.

Копирование записи через форму списка

Для независимого регистра сведений это самый быстрый способ. Откройте регистр (чаще всего он доступен через поиск по меню или через раздел настроек и справочников соответствующей конфигурации), встаньте на нужную запись и нажмите кнопку копирования в командной панели списка. Её же вызывает клавиша F9. Откроется форма новой записи, уже заполненная значениями исходной.

Что делать дальше:

  1. Измените хотя бы одно измерение или период. Если оставить ключ как есть, при записи 1С либо сообщит о дубле, либо молча заменит существующую запись.
  2. Проверьте ресурсы и реквизиты: что-то из них могло относиться к старому периоду.
  3. Нажмите «Записать и закрыть».

Это копирование одной записи, а не набора. Если у регистра включён режим записи «по регистратору», в форме списка вы вообще не увидите кнопки добавления: записи создаются только документами.

Копирование выделенных строк

В списке можно выделить несколько записей с зажатым Ctrl или Shift. Но копирование срабатывает для одной текущей строки. Для десятка записей быстрее выгрузить список в табличный документ, поправить в Excel и загрузить обратно (см. ниже).

Копирование строк табличной части

Здесь всё проще, чем с регистрами. В форме документа выделите строки и используйте копирование строки (кнопка в командной панели табличной части или F9). Строка добавится под текущей с теми же значениями.

Для массовой работы есть два приёма:

  • ✅ Копировать и вставить через буфер. Выделите строки в таблице, Ctrl+C, поставьте курсор в другую таблицу и Ctrl+V. Работает, если колонки совпадают по составу и типам. В новых релизах платформы вставка из буфера обмена в табличную часть поддерживается штатно, но лишние колонки отбрасываются.
  • ✅ Копировать документ целиком. Через кнопку копирования в списке документов. Проверьте дату и номер: новый документ получит свои, а проведение выполните отдельно.

Если табличная часть большая (сотни строк), копируйте документ целиком. Строки через буфер переносятся медленно, а ошибки в типах колонок выявляются только при записи.

Копирование набора записей программно

Когда записей много или копировать надо по условию, пишут код. Основная идея: прочитать набор, выгрузить его в таблицу значений, поправить, загрузить в другой набор и записать.

Пример: скопировать все записи независимого регистра сведений МойРегистр с измерением Подразделение из одного подразделения в другое.

Процедура СкопироватьНабор(Источник, Приемник)

	НаборИсточник = РегистрыСведений.МойРегистр.СоздатьНаборЗаписей();
	НаборИсточник.Отбор.Подразделение.Установить(Источник);
	НаборИсточник.Прочитать();

	Таблица = НаборИсточник.Выгрузить();
	Для Каждого Строка Из Таблица Цикл
		Строка.Подразделение = Приемник;
	КонецЦикла;

	НаборПриемник = РегистрыСведений.МойРегистр.СоздатьНаборЗаписей();
	НаборПриемник.Отбор.Подразделение.Установить(Приемник);
	НаборПриемник.Загрузить(Таблица);
	НаборПриемник.Записать();

КонецПроцедуры

Разберём, что здесь важно.

Отбор и замена

Записать() по умолчанию заменяет все записи, попадающие под отбор набора. Если у приёмника уже были записи с Подразделение = Приемник, они исчезнут. Хотите добавить к существующим, а не заменить, передайте параметр: НаборПриемник.Записать(Ложь). Тогда существующие записи останутся, но совпадающие по ключу будут перезаписаны.

Отбор приёмника должен совпадать со значениями, которые вы положили в таблицу. Если в таблице записи для одного подразделения, а в отборе другого, платформа выдаст ошибку.

Копирование между регистрами с одинаковой структурой

Если регистры разные, но поля совпадают по именам, таблицу загружают так же. Колонки, которых нет у приёмника, нужно удалить до загрузки, иначе платформа сообщит о несоответствии структуры. Отсутствующие колонки можно удалить в цикле по Таблица.Колонки с проверкой через метаданные приёмника.

Копирование строк табличной части в коде

Для табличной части используют Выгрузить() и Загрузить() табличной части или построчное добавление:

Для Каждого СтрокаИсточник Из ДокументИсточник.Товары Цикл
	НоваяСтрока = ДокументПриемник.Товары.Добавить();
	ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточник);
КонецЦикла;
ДокументПриемник.Записать();

ЗаполнитьЗначенияСвойств копирует только свойства с одинаковыми именами. Нужно скопировать не все колонки — третьим параметром передайте список через запятую. Служебный номер строки (НомерСтроки) платформа проставит сама.

Если приёмник — проведённый документ, а вы меняете его табличную часть, перепроведите документ. Иначе движения останутся старыми.

Массовое копирование через файл: обработка загрузки данных

Когда нужно скопировать сотни записей или править их «глазами» в таблице, удобен обмен через Excel. Алгоритм одинаков для любых регистров:

  1. Выгрузите список записей в табличный документ. В форме списка есть команда вывода списка, после неё табличный документ можно сохранить в формат Excel.
  2. Отредактируйте в Excel: измените измерения, периоды, размножьте строки.
  3. Загрузите обратно обработкой загрузки данных из табличного документа. В типовых конфигурациях такая обработка есть в разделе администрирования или в подсистеме «Загрузка данных из файла» (поиск по меню по слову «загрузка» быстро находит её).
  4. Проверьте сопоставление колонок: платформа сопоставляет их по заголовкам, лишний пробел в названии ломает привязку.

Для справочников и документов эта обработка работает из коробки. Для произвольного регистра сведений её чаще всего приходится дорабатывать: типовая обработка не знает про ваши измерения.

Типы значений в файле

Ссылочные поля (контрагент, номенклатура) в Excel — это строки, по которым 1С ищет элемент. Если наименование неоднозначно, загрузка выдаст дубль или ошибку. Для надёжности добавляйте в файл уникальный код или ИНН.

Копирование между базами: конвертация данных

Если набор нужно перенести в другую базу, смотрите в сторону механизма «Конвертация данных ». В редакции 2.0 правила обмена описывают, какие объекты выгружаются и как преобразуются. Для регистра сведений создают правило конвертации объекта, а измерения сопоставляют в правилах конвертации свойств.

Что надо знать заранее:

  • 📌 Регистр должен быть включён в правила выгрузки: «выгрузить всё» не бывает.
  • 📌 Ссылки на справочники переносятся по идентификаторам или по ключевым полям поиска. Нужные элементы справочников должны существовать в приёмнике до загрузки записей регистра, или правило должно их создавать.
  • 📌 Обмен всегда идёт в рамках одной пары конфигураций, у которых описаны правила. Для самописных регистров правила придётся дополнять.

Для разового переноса одного небольшого набора проще выгрузить его в таблицу, сохранить таблицу значений в файл через ЗначениеВСтрокуВнутр или в формат XML и загрузить в приёмнике кодом. Но это путь для разработчика. Бухгалтеру эффективнее обработка загрузки из Excel.

Выборка нужных записей перед копированием

Часто копируют не весь набор, а его часть. Тогда записи отбирают запросом, а в настройках построителя отчёта или системы компоновки данных (СКД) задают условия.

СКД удобна, когда нужен именно список на экране с настраиваемым отбором и группировкой. Результат отчёта выводится в табличный документ, который потом сохраняется в Excel. Для самого копирования в базу СКД не нужна: она читает, но не пишет. Поэтому типичная схема: СКД показывает и фильтрует, а загрузка или код записывает.

Если пишете код, отбор по условию делается в запросе:

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

Результат — таблица значений, которую меняют и загружают в НаборЗаписей.Загрузить(Таблица).

Как проверить результат и не потерять данные

После копирования сверьте количество записей до и после. Самый простой способ — открыть список регистра с отбором по нужному измерению и посмотреть число строк. В коде то же даёт НаборЗаписей.Количество() после Прочитать().

Если копируете много наборов подряд, оберните запись в транзакцию: НачатьТранзакцию(), затем все Записать(), затем ЗафиксироватьТранзакцию(). При ошибке в Исключение вызовите ОтменитьТранзакцию(). Тогда половина наборов не окажется записанной, а половина нет.

Для больших объёмов пишите порциями. Например, по одному подразделению или по одному месяцу за транзакцию. Длинная транзакция держит блокировки, и пользователи в это время будут ждать.

Ещё один приём: перед заменой сохраните исходный набор в файл. Выгрузите его в таблицу значений и запишите в XML или в текстовый файл. Если результат не устроит, вы загрузите старые записи обратно тем же кодом.

Ошибки при копировании и как их избежать

Вот что чаще всего ломается.

  • ❌ Копия «исчезла» после записи. Скорее всего, ключ совпал с существующей записью, и она заменилась. Проверьте, что хотя бы одно измерение или период отличается.
  • ❌ Вместо добавления записи — замена всего набора. Записать() без параметров заменяет всё, что подпадает под отбор. Для добавления используйте Записать(Ложь).
  • ❌ Ошибка о незаполненном измерении. У измерения может стоять запрет пустых значений. Заполните его в каждой строке таблицы до записи.
  • ❌ Записи пропали после перепроведения документа. Вы вручную правили набор регистра с регистратором. Менять надо документ.
  • ❌ Нарушена периодичность. В регистре с периодичностью «в пределах месяца» все даты внутри месяца считаются одной записью. Две записи с разными днями одного месяца склеятся.
  • ❌ Блокировка при записи. Если копируете много записей в клиент-серверной базе, а регистр используют другие пользователи, возможны ожидания на блокировках. Запускайте массовую запись в нерабочее время.

Прежде чем запускать код массовой записи в рабочей базе, проверьте его на копии базы. Откатить Записать() по условию, не имея резервной копии, нельзя.

Чек-лист перед копированием

Копирование набора записей
Выполнено: 0 / 6

Частые вопросы

Можно ли скопировать запись регистра сведений кнопкой?
Да, если регистр независимый. Нажмите «Копировать» или F9 в списке, измените ключ и запишите.
Почему в регистре накопления нет кнопки копирования?
Записи создаёт документ-регистратор. Скопируйте документ и проведите его, движения сформируются сами.
Как добавить записи в набор, не стирая существующие?
Вызывайте Записать(Ложь): параметр отключает замену. Записи с тем же ключом всё равно перезапишутся.
Чем `Выгрузить()` отличается от `Загрузить()` у набора?
Выгрузить() отдаёт записи набора таблицей значений, Загрузить() наполняет набор строками такой таблицы. Сама запись в базу происходит только после Записать().
Можно ли копировать набор между разными конфигурациями?
Через конвертацию данных или файловый обмен — да, при условии, что есть правила сопоставления измерений и справочников.