Выгрузка сохраняет A,B,C отдельно от набора. Загрузить заменяет их полностью заданными D,E, а ЗагрузитьКолонку получает сначала имя Ключ85, затем массив X,Y в порядке текущих индексов. Пустая корректная таблица затем очищает собственный набор.
Где и как запускать
Полный серверный общий модуль УчебныйПереносПерерасчета85 собственной новой конфигурации УчебныйПерерасчет85. Все помощники предоставлены; отдельная полная форма запуска дана в подготовке/supportingModules. Запуск в 1С здесь не проверялся.
Подготовка
Создайте НОВУЮ отдельную пустую учебную информационную базу на точной 8.5.1.1343 и конфигурацию УчебныйПерерасчет85. Не используйте рабочую базу или расширение готовой конфигурации. Никаких подписок, общих реквизитов, иных регистров, справочников или документов.
Конфигуратор → Планы видов расчета → новый УчебныеВидыПерерасчета85. Использование периода действия=Нет; Зависимость от видов расчета=Не использовать; список базовых планов пуст. Без собственных реквизитов/табличных частей, предопределённых видов и кода модулей.
Конфигуратор → Регистры расчета → новый УчебныйРегистрПерерасчета85. План видов расчета=УчебныеВидыПерерасчета85, периодичность=Месяц, Период действия=Нет, Базовый период=Нет. График не назначайте. Модули менеджера и набора записей пустые.
У своего регистра единственное измерение Ключ85: единственный тип Строка, длина 20, допустимая длина Переменная. Единственный ресурс Результат85: единственный тип Число, длина 12, точность 2, допустимый знак Любой. Собственных реквизитов нет.
У регистра → Перерасчеты → новый Очередь85 → Измерения → единственный Ключ85. В свойстве Измерение регистра выберите именно измерение Ключ85 родительского УчебныйРегистрПерерасчета85. Данные ведущих регистров пусты. Модуль набора записей перерасчета пуст.
Конфигуратор → Документы → новый УчебныйРегистраторПерерасчета85. Проведение=Разрешить; в Движения включите только УчебныйРегистрПерерасчета85. Собственных реквизитов и табличных частей нет. Все объектные/менеджерские модули пустые; не создавайте документ и не проводите его.
Остальные объектные модули, модули приложения и сеанса оставьте пустыми; не подключайте расширений, внешних обработчиков или подписок. Предопределённых элементов плана не создавайте. После ручной подготовки выполните проверку конфигурации и обновление учебной конфигурации базы. Здесь такая конфигурация и 1С не запускались.
Все три поля каждой своей строки: ОбъектПерерасчета — пустая ссылка именно своего документа; ВидРасчета — пустая ссылка именно своего плана; Ключ85 — собственная строка 1..20. Пустые ссылки означают незаполненные учебные ключи, не существующие документы/виды и не готовые к записи данные.
Конфигуратор → Общие → Общие модули → УчебныйПереносПерерасчета85. Создайте отдельный неглобальный серверный общий модуль: Сервер=Да, Вызов сервера=Нет, Привилегированный=Нет, оба клиентских флага и внешнее соединение=Нет, повторное использование возвращаемых значений=Не использовать. Весь основной код вставьте на уровне этого модуля, не внутрь иной процедуры.
Для ЭТОГО урока создайте собственную новую внешнюю обработку УчебныйПускПерерасчета85 с управляемой формой Форма, командой Выполнить и её кнопкой. Полный отдельный модуль формы ниже; не смешивайте его директивы с серверным общим модулем. Для другого урока используйте его собственный модуль формы и общее имя из соответствующей подготовки:
&НаКлиенте
Процедура Выполнить(Команда)
ВыполнитьНаСервере();
Сообщить("Учебный опыт завершен без записи набора в базу");
КонецПроцедуры&НаСервереБезКонтекста
Процедура ВыполнитьНаСервере()
УчебныйПереносПерерасчета85.ВыполнитьПример();
КонецПроцедуры
Процедура ВыполнитьПример() Экспорт
ПроверитьСвойСтендПерерасчета();
ОбъектПерерасчета = Документы.УчебныйРегистраторПерерасчета85.ПустаяСсылка();
ВидРасчета = ПланыВидовРасчета.УчебныеВидыПерерасчета85.ПустаяСсылка();
ПроверитьСвоиСсылки(ОбъектПерерасчета, ВидРасчета);
Набор = СоздатьСвойПустойНабор();
ПроверитьСвойПолныйПорядок(Набор, СвоиКлючи(), ОбъектПерерасчета, ВидРасчета);
ДобавитьСвоюЗапись(Набор, "A", ОбъектПерерасчета, ВидРасчета);
ДобавитьСвоюЗапись(Набор, "B", ОбъектПерерасчета, ВидРасчета);
ДобавитьСвоюЗапись(Набор, "C", ОбъектПерерасчета, ВидРасчета);
ПроверитьСвойПолныйПорядок(Набор, СвоиКлючи("A", "B", "C"), ОбъектПерерасчета, ВидРасчета);
Снимок = Набор.Выгрузить();
ПроверитьСвоюТаблицуЗагрузки(Снимок, ОбъектПерерасчета, ВидРасчета);
ПроверитьСвойСоставБезПорядка(Снимок, СвоиКлючи("A", "B", "C"), ОбъектПерерасчета, ВидРасчета);
Колонка = Набор.ВыгрузитьКолонку("Ключ85");
ПроверитьСвойМассивКлючей(Колонка, СвоиКлючи("A", "B", "C"));
Колонка[0] = "Локально85";
ПроверитьСвойМассивКлючей(Колонка, СвоиКлючи("Локально85", "B", "C"));
ПроверитьСвойПолныйПорядок(Набор, СвоиКлючи("A", "B", "C"), ОбъектПерерасчета, ВидРасчета);
ТипКлюча = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(20, ДопустимаяДлина.Переменная));
Источник = СоздатьСвоюТаблицуЗагрузки(ТипКлюча);
Для Каждого Ключ Из СвоиКлючи("D", "E") Цикл
СтрокаИсточника = Источник.Добавить();
СтрокаИсточника.ОбъектПерерасчета = ОбъектПерерасчета;
СтрокаИсточника.ВидРасчета = ВидРасчета;
СтрокаИсточника.Ключ85 = Ключ;
КонецЦикла;
ПроверитьСвоюТаблицуЗагрузки(Источник, ОбъектПерерасчета, ВидРасчета);
ПроверитьНевернуюСвоюТаблицу(Неопределено, ОбъектПерерасчета, ВидРасчета);
НеполныйИсточник = Новый ТаблицаЗначений;
НеполныйИсточник.Колонки.Добавить("Ключ85", ТипКлюча);
ПроверитьНевернуюСвоюТаблицу(НеполныйИсточник, ОбъектПерерасчета, ВидРасчета);
НеверныйТипКлюча = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(2, 0));
НеверныйИсточник = СоздатьСвоюТаблицуЗагрузки(НеверныйТипКлюча);
ПроверитьНевернуюСвоюТаблицу(НеверныйИсточник, ОбъектПерерасчета, ВидРасчета);
ПроверитьСвойПолныйПорядок(Набор, СвоиКлючи("A", "B", "C"), ОбъектПерерасчета, ВидРасчета);
Набор.Загрузить(Источник);
ПроверитьСвойСоставБезПорядка(Набор, СвоиКлючи("D", "E"), ОбъектПерерасчета, ВидРасчета);
ПроверитьСвойСоставБезПорядка(Снимок, СвоиКлючи("A", "B", "C"), ОбъектПерерасчета, ВидРасчета);
Значения = СвоиКлючи("X", "Y");
ПроверитьНеверныйСвойВводКолонки(Неопределено, Значения, 2);
ПроверитьНеверныйСвойВводКолонки(Значения, "Ключ85", 2);
ПроверитьНеверныйСвойВводКолонки("ДругойКлюч", Значения, 2);
ПроверитьНеверныйСвойВводКолонки("Ключ85", Неопределено, 2);
ПроверитьНеверныйСвойВводКолонки("Ключ85", СвоиКлючи("X"), 2);
ПроверитьНеверныйСвойВводКолонки("Ключ85", СвоиКлючи("X", "Y", "Z"), 2);
ПовторныеЗначения = СвоиКлючи("X", "X");
ПроверитьНеверныйСвойВводКолонки("Ключ85", ПовторныеЗначения, 2);
НеверныеЗначения = Новый Массив;
НеверныеЗначения.Добавить(1);
НеверныеЗначения.Добавить("Y");
ПроверитьНеверныйСвойВводКолонки("Ключ85", НеверныеЗначения, 2);
ПроверитьСвойСоставБезПорядка(Набор, СвоиКлючи("D", "E"), ОбъектПерерасчета, ВидРасчета);
ПроверитьСвойВводКолонки("Ключ85", Значения, Набор.Количество());
Набор.ЗагрузитьКолонку("Ключ85", Значения);
ПроверитьСвойПолныйПорядок(Набор, СвоиКлючи("X", "Y"), ОбъектПерерасчета, ВидРасчета);
Значения[0] = "Позднее85";
ПроверитьСвойПолныйПорядок(Набор, СвоиКлючи("X", "Y"), ОбъектПерерасчета, ВидРасчета);
ПроверитьСвойМассивКлючей(Набор.ВыгрузитьКолонку("Ключ85"), СвоиКлючи("X", "Y"));
ПроверитьСвойСоставБезПорядка(Источник, СвоиКлючи("D", "E"), ОбъектПерерасчета, ВидРасчета);
ПустойИсточник = СоздатьСвоюТаблицуЗагрузки(ТипКлюча);
ПроверитьСвоюТаблицуЗагрузки(ПустойИсточник, ОбъектПерерасчета, ВидРасчета);
Набор.Загрузить(ПустойИсточник);
ПроверитьСвойПолныйПорядок(Набор, СвоиКлючи(), ОбъектПерерасчета, ВидРасчета);
ПроверитьСвойМассивКлючей(Набор.ВыгрузитьКолонку("Ключ85"), СвоиКлючи());
ПроверитьСвойСоставБезПорядка(Снимок, СвоиКлючи("A", "B", "C"), ОбъектПерерасчета, ВидРасчета);
КонецПроцедуры
Процедура ПроверитьСвойСтендПерерасчета()
Если Метаданные.Документы.Количество() <> 1 Или Метаданные.ПланыВидовРасчета.Количество() <> 1 Или Метаданные.РегистрыРасчета.Количество() <> 1 Или Метаданные.Справочники.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Тогда
ВызватьИсключение "Нужен именно собственный минимальный стенд УчебныйПерерасчет85";
КонецЕсли;
МетаДокумент = Метаданные.Документы.Найти("УчебныйРегистраторПерерасчета85");
МетаПлан = Метаданные.ПланыВидовРасчета.Найти("УчебныеВидыПерерасчета85");
МетаРегистр = Метаданные.РегистрыРасчета.Найти("УчебныйРегистрПерерасчета85");
Если МетаДокумент = Неопределено Или МетаПлан = Неопределено Или МетаРегистр = Неопределено Тогда
ВызватьИсключение "Не найдены свои документ, план видов расчета и регистр расчета";
КонецЕсли;
Свойства = Метаданные.СвойстваОбъектов;
Если МетаДокумент.Проведение <> Свойства.Проведение.Разрешить
Или МетаДокумент.Реквизиты.Количество() <> 0 Или МетаДокумент.ТабличныеЧасти.Количество() <> 0
Или МетаДокумент.Движения.Количество() <> 1 Или Не МетаДокумент.Движения.Содержит(МетаРегистр) Тогда
ВызватьИсключение "Документ должен иметь единственное движение по своему регистру, без своих полей";
КонецЕсли;
Если МетаПлан.ИспользованиеПериодаДействия
Или МетаПлан.ЗависимостьОтВидовРасчета <> Свойства.ИспользованиеБазыПланаВидовРасчета.НеИспользовать
Или МетаПлан.БазовыеВидыРасчета.Количество() <> 0
Или МетаПлан.Реквизиты.Количество() <> 0 Или МетаПлан.ТабличныеЧасти.Количество() <> 0 Тогда
ВызватьИсключение "План должен быть без периода действия, базы и собственных полей";
КонецЕсли;
Если МетаРегистр.ПланВидовРасчета <> МетаПлан
Или МетаРегистр.Периодичность <> Свойства.ПериодичностьРегистраРасчета.Месяц
Или МетаРегистр.ПериодДействия Или МетаРегистр.БазовыйПериод
Или МетаРегистр.Измерения.Количество() <> 1 Или МетаРегистр.Ресурсы.Количество() <> 1
Или МетаРегистр.Реквизиты.Количество() <> 0 Или МетаРегистр.Перерасчеты.Количество() <> 1 Тогда
ВызватьИсключение "Свой месячный регистр должен иметь одно измерение, один ресурс и один перерасчет";
КонецЕсли;
МетаКлюч = МетаРегистр.Измерения.Найти("Ключ85");
МетаРесурс = МетаРегистр.Ресурсы.Найти("Результат85");
МетаПерерасчет = МетаРегистр.Перерасчеты.Найти("Очередь85");
Если МетаКлюч = Неопределено Или МетаРесурс = Неопределено Или МетаПерерасчет = Неопределено Тогда
ВызватьИсключение "Не найдены Ключ85, Результат85 или Очередь85 собственного регистра";
КонецЕсли;
Если МетаКлюч.Тип.Типы().Количество() <> 1 Или Не МетаКлюч.Тип.СодержитТип(Тип("Строка")) Тогда
ВызватьИсключение "Родительское измерение должно иметь единственный тип Строка";
КонецЕсли;
Если МетаКлюч.Тип.КвалификаторыСтроки.Длина <> 20
Или МетаКлюч.Тип.КвалификаторыСтроки.ДопустимаяДлина <> ДопустимаяДлина.Переменная Тогда
ВызватьИсключение "Родительское измерение должно быть строкой переменной длины до 20";
КонецЕсли;
Если МетаРесурс.Тип.Типы().Количество() <> 1 Или Не МетаРесурс.Тип.СодержитТип(Тип("Число")) Тогда
ВызватьИсключение "Ресурс собственного регистра должен иметь единственный тип Число";
КонецЕсли;
Если МетаРесурс.Тип.КвалификаторыЧисла.Разрядность <> 12
Или МетаРесурс.Тип.КвалификаторыЧисла.РазрядностьДробнойЧасти <> 2
Или МетаРесурс.Тип.КвалификаторыЧисла.ДопустимыйЗнак <> ДопустимыйЗнак.Любой Тогда
ВызватьИсключение "Ресурс должен иметь собственный тип Число(12,2), любой знак";
КонецЕсли;
Если МетаПерерасчет.Измерения.Количество() <> 1 Тогда
ВызватьИсключение "Очередь85 должна иметь единственное измерение";
КонецЕсли;
МетаКлючПерерасчета = МетаПерерасчет.Измерения.Найти("Ключ85");
Если МетаКлючПерерасчета = Неопределено Тогда
ВызватьИсключение "Не найден Ключ85 своего перерасчета";
КонецЕсли;
Если МетаКлючПерерасчета.ИзмерениеРегистра <> МетаКлюч
Или МетаКлючПерерасчета.ДанныеВедущихРегистров.Количество() <> 0 Тогда
ВызватьИсключение "Измерение перерасчета должно ссылаться на свой Ключ85, без ведущих регистров";
КонецЕсли;
КонецПроцедуры
Функция СоздатьСвойПустойНабор()
Набор = РегистрыРасчета.УчебныйРегистрПерерасчета85.Перерасчеты.Очередь85.СоздатьНаборЗаписей();
МетаПерерасчет = Метаданные.РегистрыРасчета.УчебныйРегистрПерерасчета85.Перерасчеты.Очередь85;
Если Набор.Количество() <> 0 Или Набор.Метаданные() <> МетаПерерасчет Тогда
ВызватьИсключение "Создан не пустой набор своего перерасчета Очередь85";
КонецЕсли;
Возврат Набор;
КонецФункции
Функция СвоиКлючи(Первый = Неопределено, Второй = Неопределено, Третий = Неопределено)
Ключи = Новый Массив;
Кандидаты = Новый Массив;
Кандидаты.Добавить(Первый);
Кандидаты.Добавить(Второй);
Кандидаты.Добавить(Третий);
Для Каждого Ключ Из Кандидаты Цикл
Если ТипЗнч(Ключ) <> Тип("Неопределено") Тогда
ПроверитьСвойКлюч(Ключ);
Ключи.Добавить(Ключ);
КонецЕсли;
КонецЦикла;
Возврат Ключи;
КонецФункции
Процедура ПроверитьСвойКлюч(Ключ)
Если ТипЗнч(Ключ) <> Тип("Строка") Тогда
ВызватьИсключение "Собственный ключ должен иметь тип Строка";
КонецЕсли;
Если СтрДлина(Ключ) < 1 Или СтрДлина(Ключ) > 20 Тогда
ВызватьИсключение "Собственный ключ должен иметь длину от 1 до 20";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьСвоиСсылки(ОбъектПерерасчета, ВидРасчета)
Если ТипЗнч(ОбъектПерерасчета) <> Тип("ДокументСсылка.УчебныйРегистраторПерерасчета85")
Или ТипЗнч(ВидРасчета) <> Тип("ПланВидовРасчетаСсылка.УчебныеВидыПерерасчета85") Тогда
ВызватьИсключение "Нужны ссылки только своего подготовленного документа и плана";
КонецЕсли;
Если ОбъектПерерасчета <> Документы.УчебныйРегистраторПерерасчета85.ПустаяСсылка()
Или ВидРасчета <> ПланыВидовРасчета.УчебныеВидыПерерасчета85.ПустаяСсылка() Тогда
ВызватьИсключение "В этом черновом опыте оба ссылочных ключа должны быть явно пустыми";
КонецЕсли;
КонецПроцедуры
Функция ДобавитьСвоюЗапись(Набор, Ключ, ОбъектПерерасчета, ВидРасчета)
ПроверитьСвойКлюч(Ключ);
ПроверитьСвоиСсылки(ОбъектПерерасчета, ВидРасчета);
Для Каждого Существующая Из Набор Цикл
Если Существующая.Ключ85 = Ключ Тогда
ВызватьИсключение "Наш собственный черновик не принимает повтор ключа";
КонецЕсли;
КонецЦикла;
Запись = Набор.Добавить();
Запись.ОбъектПерерасчета = ОбъектПерерасчета;
Запись.ВидРасчета = ВидРасчета;
Запись.Ключ85 = Ключ;
Возврат Запись;
КонецФункции
Процедура ПроверитьСвоюЗапись(Запись, Ключ, ОбъектПерерасчета, ВидРасчета)
ПроверитьСвоиСсылки(Запись.ОбъектПерерасчета, Запись.ВидРасчета);
ПроверитьСвойКлюч(Запись.Ключ85);
Если Запись.ОбъектПерерасчета <> ОбъектПерерасчета Или Запись.ВидРасчета <> ВидРасчета Или Запись.Ключ85 <> Ключ Тогда
ВызватьИсключение "Полный состав трех полей собственной строки не совпал";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьСвойПолныйПорядок(Набор, Ключи, ОбъектПерерасчета, ВидРасчета)
Если Набор.Количество() <> Ключи.Количество() Тогда
ВызватьИсключение "Не совпало количество строк своего чернового набора";
КонецЕсли;
Если Ключи.Количество() > 0 Тогда
Для Индекс = 0 По Ключи.Количество() - 1 Цикл
Запись = Набор.Получить(Индекс);
ПроверитьСвоюЗапись(Запись, Ключи[Индекс], ОбъектПерерасчета, ВидРасчета);
ПроверитьСвоюЗапись(Набор[Индекс], Ключи[Индекс], ОбъектПерерасчета, ВидРасчета);
Если Набор.Индекс(Запись) <> Индекс Тогда
ВызватьИсключение "Индекс собственной полученной записи не совпал";
КонецЕсли;
КонецЦикла;
КонецЕсли;
Сообщить("Проверены все три поля, их типы и порядок: строк=" + Строка(Набор.Количество()));
КонецПроцедуры
Функция СоздатьСвоюТаблицуЗагрузки(ТипКлюча)
Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить("ОбъектПерерасчета", Новый ОписаниеТипов("ДокументСсылка.УчебныйРегистраторПерерасчета85"));
Таблица.Колонки.Добавить("ВидРасчета", Новый ОписаниеТипов("ПланВидовРасчетаСсылка.УчебныеВидыПерерасчета85"));
Таблица.Колонки.Добавить("Ключ85", ТипКлюча);
Возврат Таблица;
КонецФункции
Процедура ПроверитьСвоюКолонку(Таблица, Имя, ОжидаемыйТип)
Колонка = Таблица.Колонки.Найти(Имя);
Если Колонка = Неопределено Тогда
ВызватьИсключение "В собственной таблице отсутствует требуемая колонка";
КонецЕсли;
Если Колонка.ТипЗначения.Типы().Количество() <> 1 Или Не Колонка.ТипЗначения.СодержитТип(ОжидаемыйТип) Тогда
ВызватьИсключение "У собственной колонки должен быть единственный подготовленный тип";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьСвоюТаблицуЗагрузки(Таблица, ОбъектПерерасчета, ВидРасчета)
Если ТипЗнч(Таблица) <> Тип("ТаблицаЗначений") Тогда
ВызватьИсключение "Собственный источник загрузки должен быть ТаблицаЗначений";
КонецЕсли;
Если Таблица.Колонки.Количество() <> 3 Тогда
ВызватьИсключение "Собственная таблица должна иметь ровно три подготовленные колонки";
КонецЕсли;
ПроверитьСвоюКолонку(Таблица, "ОбъектПерерасчета", Тип("ДокументСсылка.УчебныйРегистраторПерерасчета85"));
ПроверитьСвоюКолонку(Таблица, "ВидРасчета", Тип("ПланВидовРасчетаСсылка.УчебныеВидыПерерасчета85"));
ПроверитьСвоюКолонку(Таблица, "Ключ85", Тип("Строка"));
Квалификаторы = Таблица.Колонки.Найти("Ключ85").ТипЗначения.КвалификаторыСтроки;
Если Квалификаторы.Длина <> 20 Или Квалификаторы.ДопустимаяДлина <> ДопустимаяДлина.Переменная Тогда
ВызватьИсключение "Ключ собственной таблицы должен быть строкой переменной длины до 20";
КонецЕсли;
Найденные = Новый Массив;
Для Каждого СтрокаТаблицы Из Таблица Цикл
ПроверитьСвоюЗапись(СтрокаТаблицы, СтрокаТаблицы.Ключ85, ОбъектПерерасчета, ВидРасчета);
Если Найденные.Найти(СтрокаТаблицы.Ключ85) <> Неопределено Тогда
ВызватьИсключение "Собственная таблица не принимает повтор ключа";
КонецЕсли;
Найденные.Добавить(СтрокаТаблицы.Ключ85);
КонецЦикла;
КонецПроцедуры
Процедура ПроверитьСвойСоставБезПорядка(Коллекция, Ключи, ОбъектПерерасчета, ВидРасчета)
Если Коллекция.Количество() <> Ключи.Количество() Тогда
ВызватьИсключение "Не совпало количество строк собственной коллекции";
КонецЕсли;
Найденные = Новый Массив;
Для Каждого Запись Из Коллекция Цикл
ПроверитьСвоюЗапись(Запись, Запись.Ключ85, ОбъектПерерасчета, ВидРасчета);
Если Ключи.Найти(Запись.Ключ85) = Неопределено Или Найденные.Найти(Запись.Ключ85) <> Неопределено Тогда
ВызватьИсключение "Полный собственный состав ключей не совпал";
КонецЕсли;
Найденные.Добавить(Запись.Ключ85);
КонецЦикла;
КонецПроцедуры
Процедура ПроверитьСвойМассивКлючей(Значения, Ожидание)
Если ТипЗнч(Значения) <> Тип("Массив") Тогда
ВызватьИсключение "Выгрузка собственной колонки должна иметь тип Массив";
КонецЕсли;
Если Значения.Количество() <> Ожидание.Количество() Тогда
ВызватьИсключение "Не совпал размер собственного массива ключей";
КонецЕсли;
Если Ожидание.Количество() > 0 Тогда
Для Индекс = 0 По Ожидание.Количество() - 1 Цикл
ПроверитьСвойКлюч(Значения[Индекс]);
Если Значения[Индекс] <> Ожидание[Индекс] Тогда
ВызватьИсключение "Полный порядок собственной колонки не совпал";
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьСвойВводКолонки(ИмяПоля, Значения, Количество)
Если ТипЗнч(ИмяПоля) <> Тип("Строка") Тогда
ВызватьИсключение "Первым аргументом нашего ввода колонки должно быть имя-Строка";
КонецЕсли;
Если ИмяПоля <> "Ключ85" Тогда
ВызватьИсключение "Наш опыт загрузки колонки допускает только Ключ85";
КонецЕсли;
Если ТипЗнч(Значения) <> Тип("Массив") Тогда
ВызватьИсключение "Вторым аргументом нашего ввода колонки должен быть Массив";
КонецЕсли;
Если Значения.Количество() <> Количество Тогда
ВызватьИсключение "Наш ввод колонки требует ровно одно значение на каждый текущий индекс";
КонецЕсли;
Найденные = Новый Массив;
Для Каждого Ключ Из Значения Цикл
ПроверитьСвойКлюч(Ключ);
Если Найденные.Найти(Ключ) <> Неопределено Тогда
ВызватьИсключение "Наш ввод колонки не принимает повтор ключа";
КонецЕсли;
Найденные.Добавить(Ключ);
КонецЦикла;
КонецПроцедуры
Процедура ПроверитьНеверныйСвойВводКолонки(ИмяПоля, Значения, Количество)
Отклонен = Ложь;
Попытка
ПроверитьСвойВводКолонки(ИмяПоля, Значения, Количество);
Исключение
Отклонен = Истина;
Сообщить("Ручной опыт: неверный собственный ввод колонки отклонен. " + ОписаниеОшибки());
КонецПопытки;
Если Не Отклонен Тогда
ВызватьИсключение "Ожидалось отклонение собственного неверного ввода колонки";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьНевернуюСвоюТаблицу(Таблица, ОбъектПерерасчета, ВидРасчета)
Отклонена = Ложь;
Попытка
ПроверитьСвоюТаблицуЗагрузки(Таблица, ОбъектПерерасчета, ВидРасчета);
Исключение
Отклонена = Истина;
Сообщить("Ручной опыт: неверная собственная таблица отклонена. " + ОписаниеОшибки());
КонецПопытки;
Если Не Отклонена Тогда
ВызватьИсключение "Ожидалось отклонение собственной неверной таблицы";
КонецЕсли;
КонецПроцедурыУчебныйПускПерерасчета85.Форма
Собственная новая внешняя обработка УчебныйПускПерерасчета85 → Управляемая форма Форма → Модуль
Отдельный полный модуль собственной формы запуска именно этого урока; здесь не запускался.
&НаКлиенте
Процедура Выполнить(Команда)
ВыполнитьНаСервере();
Сообщить("Учебный опыт завершен без записи набора в базу");
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ВыполнитьНаСервере()
УчебныйПереносПерерасчета85.ВыполнитьПример();
КонецПроцедурыРазбор по шагам
Сначала read-only проверить весь свой минимальный стенд и создать новый пустой набор. Его три первоначальные строки A,B,C подготовлены полностью нашим кодом.
Выгрузить() native возвращает ТаблицаЗначений и копирует набор. При единственном измерении и отсутствии общих реквизитов должны быть ровно ОбъектПерерасчета,ВидРасчета,Ключ85. Проверить имена, типы колонок и все значения всех строк без предположения о порядке выгруженной таблицы.
ВыгрузитьКолонку("Ключ85") native возвращает Массив, причём прямо фиксирует порядок индексов. Проверить A,B,C, затем изменить только первый элемент массива на Локально85. Набор остаётся A,B,C.
Создать собственную таблицу из трёх явно типизированных колонок конкретного документа, конкретного плана и строки переменной длины 20. Две строки D,E содержат те же явно пустые собственные ссылки.
До Загрузить проверить всю таблицу: ровно три требуемые колонки с единственными типами, квалификаторы ключа, все ссылочные и строковые значения, отсутствие повторных собственных ключей. Не полагаться на неявное преобразование неподходящих данных.
Неопределено, таблица только с Ключ85 и полноценная таблица с числовым типом Ключ85 должны отклоняться нашим валидатором до Загрузить. Создание этих намеренно плохих таблиц находится вне ожидаемого catch; ошибки подготовки не скрываются.
Native Загрузить очищает набор и заполняет доступные writable свойства совпавших имён. После загрузки строго проверить набор из D,E, без A,B,C, но не приписывать методу отдельно недокументированный порядок строк таблицы.
Снимок выгрузки всё ещё полностью A,B,C. Источник загрузки остаётся D,E. Это собственные отдельные таблицы памяти, не чтение зарегистрированной очереди.
Наш ввод колонки принимает только имя-Строка Ключ85 и Массив ровно текущей длины, с уникальными строками 1..20. Восемь плохих входов проверяются без вызова метода: отсутствие/перестановка аргументов, другое имя, отсутствие массива, короткий/длинный массив, повтор и число вместо строки.
Правильный native порядок: ЗагрузитьКолонку("Ключ85", Значения). Оба аргумента указаны явно; в установленной справке они помечены необязательными, но значения по умолчанию и эффект их пропуска этим опытом не угадываются.
Native загрузка колонки идёт по текущим индексам. Поэтому после массива X,Y запись 0 содержит X, запись 1 Y; обе пустые ссылочные колонки должны сохраниться. Их прежний порядок D/E после общей загрузки не нужен для этой проверки.
После изменения исходного массива X на Позднее85 повторно проверить текущий набор X,Y и его новую выгрузку колонки X,Y. Строковые значения уже скопированы, изменение массива не является новым вызовом загрузки.
Загрузить полностью подготовленную пустую таблицу тех же трёх типов. Native сначала очищает набор; результат пуст, выгруженная колонка тоже пустая. Снимок A,B,C остаётся независимым.
Ни один ожидаемый catch не охватывает Выгрузить, ВыгрузитьКолонку, Загрузить или ЗагрузитьКолонку. Неожиданная ошибка реального API прерывает опыт; работа с базой нигде не выполняется.
Как проверить результат
Снимок содержит полный набор трёх полей A,B,C со своими пустыми ссылками; исходная выгруженная колонка имеет точный порядок A,B,C.
Изменение массива выгрузки не меняет набор. После Загрузить полный набор D,E, без прежних A,B,C; снимок всё ещё A,B,C.
Три неподходящих собственных источника таблицы и восемь плохих входов колонки отклоняются до реальных операций; полный прежний состав проверяется снова.
После ЗагрузитьКолонку индексы 0/1 содержат X/Y, обе ссылочные колонки имеют прежние конкретные типы и пустые значения. Позднее изменение массива не меняет X/Y.
Загрузка правильной пустой таблицы очищает только этот набор. Выгрузка его колонки даёт пустой массив; таблицы снимка A,B,C и источника D,E остаются прежними.
Ожидаемый результат
Полный самостоятельный модуль выполняет конкретное редактирование только собственного чернового набора в памяти и проверяет все поля результата. Это не перерасчёт записанных движений и не выполнение нами внутри 1С.
На что обратить внимание
ВыгрузитьКолонки не используется и не получает привязку: непосредственная установленная справка не содержит возвращаемого значения, хотя описание говорит о создании таблицы. Назначать такой недоказанный результат переменной нельзя.
ЗагрузитьКолонку у перерасчета получает ИмяПоля перед Массив. Не копировать обратный порядок из другого типа набора, даже если названия методов похожи.
Точное совпадение длины массива, уникальность ключей и три обязательные колонки — дополнительные правила нашего ввода. Поведение native для короткого/длинного массива, отсутствующих колонок и неверных типов не выдаётся за эти правила.
Загрузить заменяет набор в памяти, но не создаёт зарегистрированную запись. Пустые ссылочные ключи не становятся заполненными только потому, что копирование успешно.
Ресурс Результат85 принадлежит регистру расчета, не строке перерасчета. В этой таблице он отсутствует намеренно, как и неподготовленные общие реквизиты.
Ни Прочитать, ни Записать, ни восстановление записанного набора не используются. СоздатьНаборЗаписей даёт новый пустой набор; все строки добавлены или загружены нашим кодом. Удаление и очистка затрагивают только этот набор в памяти.
ЭтотОбъект не используется: основной код находится в серверном общем модуле, а модуль набора перерасчета пуст. Свойство отсутствующего модульного контекста не подменяется параметром.
Read-only guard сверяет доступную собственную схему перед созданием набора. Пустые остальные модули, отсутствие расширений и предопределённых элементов заданы точной подготовкой; guard не обещает анализа текстов сторонних модулей или проверки произвольной установленной конфигурации.
В native ИзмерениеРегистра текст описывает измерение, но строка Тип называет РегистрРасчета. Код не угадывает ТипЗнч этого метаобъекта: сравнивает его с настоящим подготовленным родительским измерением. Тип строкового поля проверяется у родителя.
Python-проверки — модель полностью заданных собственных значений и статическая сверка API установленной 8.5.1.1343. Они не выполняют BSL, не создают конфигурацию и не доказывают успешный опыт в 1С.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.