Как я пытался применить ИИ для обработки номенклатуры

Клиенту понадобилось перенести артикул из полей «Аналог 1», «Аналог 2», «Аналог 3» в одно поле Аналоги через запятую.

Решил поручить эту задачу искустенному интеллекту. Промпт:

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

Код перебирает все позиции, что плохо, предложил ускорить:

Ускорь этот код, чтобы позиции отбирались запросом
Процедура ОбновитьАналоги()
    // Создаем запрос для выборки необходимых данных из справочника Номенклатура
    Запрос = Новый Запрос(
        "ВЫБРАТЬ
            Номенклатура.Ссылка КАК Ссылка,
            Номенклатура.Аналог1 КАК Аналог1,
            Номенклатура.Аналог2 КАК Аналог2,
            Номенклатура.Аналог3 КАК Аналог3
        ИЗ
            Справочник.Номенклатура КАК Номенклатура"
    );

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

        // Обновляем поле Аналоги текущего элемента
        Номенклатура = Справочники.Номенклатура.НайтиПоСсылке(Ссылка);
        Номенклатура.Аналоги = Аналоги;
        
        // Сохраняем изменения
        Номенклатура.Записать();
    КонецЦикла;
КонецПроцедуры

В лучших традициях джуна если его попросили использовать запросы, он их использовал, а зачем, не понял.

Я попробовал еще раз:

ускорь, чтобы в запросе отбирались только те позиции, где поля аналог1-3 заполнены
Процедура ОбновитьАналоги()
    // Создаем запрос для выборки необходимых данных из справочника Номенклатура
    Запрос = Новый Запрос(
        "ВЫБРАТЬ
            Номенклатура.Ссылка КАК Ссылка,
            Номенклатура.Аналог1 КАК Аналог1,
            Номенклатура.Аналог2 КАК Аналог2,
            Номенклатура.Аналог3 КАК Аналог3
        ИЗ
            Справочник.Номенклатура КАК Номенклатура
        ГДЕ
            Номенклатура.Аналог1 <> NULL И
            Номенклатура.Аналог2 <> NULL И
            Номенклатура.Аналог3 <> NULL"
    );

    //Далее как в прошлом случае
    //...
КонецПроцедуры

Как видно, ИИ забыл о чем была первоначальная задача и вместо ИЛИ в условиях запроса использовал И. К тому же это удаление последней запятой тоже конечно, смешной способ. На этом моё терпение лопнуло, я взял последний вариант и переписал его адекватно:


&НаСервере
Процедура ОбработатьНаСервере()
	// Создаем запрос для выборки необходимых данных из справочника Номенклатура
	Запрос = Новый Запрос(
	"ВЫБРАТЬ
	|	Номенклатура.Ссылка КАК Ссылка,
	|	ЕСТЬNULL(Номенклатура.Аналог1.Артикул, """") КАК Аналог1,
	|	ЕСТЬNULL(Номенклатура.Аналог2.Артикул, """") КАК Аналог2,
	|	ЕСТЬNULL(Номенклатура.Аналог3.Артикул, """") КАК Аналог3
	|ИЗ
	|	Справочник.Номенклатура КАК Номенклатура
	|ГДЕ
	|	(Номенклатура.Аналог1 <> ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
	|			ИЛИ Номенклатура.Аналог2 <> ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
	|			ИЛИ Номенклатура.Аналог3 <> ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка))"
	);
	
	// Выполняем запрос
	Результат = Запрос.Выполнить().Выбрать();
	
	// Обрабатываем результаты запроса
	Пока Результат.Следующий() Цикл
		
		// Получаем ссылку на текущий элемент
		Ссылка = Результат.Ссылка;
		
		// Создаем пустую строку для хранения аналогов
		М = Новый Массив();;
		
		// Проверяем каждое поле на заполненность и добавляем артикул в строку
		Для Инд = 1 По 3 Цикл         
			Зн = СокрЛП(Результат["Аналог" + Инд]);
			Если ЗначениеЗаполнено(Зн) Тогда
				М.Добавить(Зн);
			КонецЕсли;
		КонецЦикла;
		
		// У обновляем поле Аналоги текущего элемента
		Если М.Количество() > 0 Тогда
			ОО = Результат.Ссылка.ПолучитьОбъект();          
			Аналоги = СтрСоединить(М, ",");
			ОО.Аналоги = Аналоги;
			Сообщить("" + Результат.Ссылка + " >> " + Аналоги);
			
			// Сохраняем изменения       
			Если Записывать Тогда
				ОО.Записать();     
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры

&НаКлиенте
Процедура Обработать(Команда)
	ОбработатьНаСервере();
КонецПроцедуры

ИИ высоко оценил мой код:

Ваш код выглядит хорошо и эффективно решает задачу. Он использует запрос для выборки данных из справочника «Номенклатура», проверяет наличие аналогов и формирует строку с артикулами, если они заполнены. Давайте разберем его по частям и выделим ключевые моменты:

  1. Запрос:
    – Используется конструкция ЕСТЬNULL, чтобы избежать ошибок при отсутствии значений в полях аналогов.
    – Условия в блоке ГДЕ проверяют, что хотя бы одно из полей аналогов заполнено, что оптимизирует выборку.
  2. Обработка результатов:
    – Результаты запроса обрабатываются в цикле, где для каждого элемента проверяется наличие значений в полях «Аналог1», «Аналог2» и «Аналог3».
    – Если значение заполнено, оно добавляется в массив М.
  3. Формирование строки аналогов:
    – Если массив М содержит значения, они соединяются в строку с помощью функции СтрСоединить, и обновляется поле «Аналоги» текущего элемента.
    – Выводится сообщение о том, какие аналоги были добавлены для текущего элемента.
  4. Сохранение изменений:
    – Изменения сохраняются только если переменная Записывать установлена в Истина, что позволяет контролировать процесс записи.

Код хорошо структурирован и читаем. Если у вас есть дополнительные вопросы или вы хотите внести изменения, дайте знать!

Среда: Нетленка Объем: 0.5 час