@Gioo12x

Как исправить мой код 1С: Предприятие нахождение максимального элемента в табличной части чтоб он не выдавал ошибку?

Я уже третий день не могу понять какая ошибка в моём коде.
Сам код в теории правильный но выдаёт ошибку "Итератор для значение не определён"
Вот условие данного кода: Отобразить вариант головного убора, с наибольшим количеством
материалов, участвующих в изготовлении.
Вот сам код который надо исправить:
Выборка=Справочники.Варианты_головных_уборов.Выбрать(); 
	Макс2=0;
	Для каждого а из Выборка.ТабличнаяЧасть1 Цикл
		Если Макс2>а.Количество_материалов тогда
			Макс2=а.Количество_материалов;
		КонецЕсли;        		
	КонецЦикла; 
		Сообщить(макс2.Количество_материалов);
  • Вопрос задан
  • 64 просмотра
Решения вопроса 1
@Dementor
программист, архитектор, аналитик
Давайте смотреть, что не так с вашим кодом без детального анализа, а просто что сразу бросается в глаза:
  1. Поломанное форматирование. Пока 8 строчек как тут - это просто эстетическая боль, но когда строчек 80, 800 или 8000, то это маскирует ошибки, на которые уйдет больше чем три дня
  2. Снова таки, с точки зрения облегчения восприятия, нужно все делать в едином стиле - делаете переменные с маленькой буквы - они все должны быть с маленькой, а делаете с большой, то все уже с большой. В коде половина маленькие, половина большие без какой-либо систему. То же замечание касается ключевых слов - если не используете системное автодополнение, которое само за вас все ключевые слова пишет с большой буквы, и по личным предпочтениям начинаете писать с маленькой - то пишите с маленькой уже все подряд, а не "тогда" с маленькой, а "Цикл" с большой
  3. Использование переменных в духе "а и б сидели на трубе" крайне не рекомендовано - все переменные должны в своем имени отражать свое содержимое. Если лень писать СтрокаТабличнойЧастиГоловныхУборов, то хотя бы СтрокаТЧ, но никогда не "а"!!!
  4. Выборка из менеджера объекта полезная штука для некоторых сценариев, но конкретно тут просто увеличивается "углеродный след". Достаточно выполнить запрос сразу к табличной части, в котором тут же получить максимальное количество, а не вытаскивать в оперативку все объекты
  5. Вы уверены, что в табличной части запрещены отрицательные числа? На каком основании в переменную для сравнения вы размещаете ноль?
  6. Для вас же было бы понятнее, если бы вы не использовали явное сравнение, в котором допустили ошибку, а воспользовались стандартной функцией Макс()
  7. Ну и на финал, этот некрасивый и абсолютно не оптимальный код может даже заработать (но выдавать неправильное значение), если из переменной Макс2 (смотрим пункт №3 про нормальные наименования) типа Число не пытаться прочитать свойство "Количество_материалов". Такое ощущение, что было несколько черновиков кода и в одном из них сохранялось не максимальное значение, а сама строка табличной части, а потом все варианты свалили в единую кучу


Upd. Я смотрел поверхностно, но другие более детально и подсказали в комментариях про необходимость обхода выборки данных с помощью метода Следующий().

Итого, если не переписывать на запрос, то правильный код будет следующим:

Выборка=Справочники.Варианты_головных_уборов.Выбрать(); 
МаксКоличество = Неопределено;
Пока Выборка.Следующий() Цикл
	Для каждого СтрокаКоличества  из Выборка.ТабличнаяЧасть1 Цикл
		Если МаксКоличество = Неопределено тогда
			МаксКоличество = СтрокаКоличества.Количество_материалов;
		Иначе
			МаксКоличество = Макс(МаксКоличество, СтрокаКоличества.Количество_материалов);
		КонецЕсли;        		
	КонецЦикла; 
КонецЦикла; 
МаксКоличество = ?(МаксКоличество=Неопределено, 0, МаксКоличество);
Сообщить(МаксКоличество);
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
@kalapanga
По алгоритму:
1) Максимум ищете неверно. Макс2 у Вас всегда останется 0. Нужно:
Если Макс2 < а.Количество_материалов ...
2) Макс2 - это только само максимальное количество материалов. Если Вам нужно вывести именно вариант, то его отдельно нужно запоминать, чтобы потом сообщить.
3) Следует учесть, что вариантов с одинаковым количеством материалов (равным максимальному) может быть несколько.
По ошибке Вам уже написали.
Стоит попробовать сделать это всё запросом.
Ответ написан
Комментировать
Mikhail_E
@Mikhail_E
1С, SQL
Ужас какой.
Если по вашему коду тогда так :
Выборка=Справочники.Варианты_головных_уборов.Выбрать(); 
Пока Выборка.Следующий() Цикл
	Макс2=0;
		Для каждого а из Выборка.ТабличнаяЧасть1 Цикл
			Если Макс2>а.Количество_материалов тогда
				Макс2=а.Количество_материалов;
			КонецЕсли;        		
		КонецЦикла; 
			Сообщить(макс2.Количество_материалов);
КонецЦикла;

А вообще это запросом делается конечно.
Запрос = Новый Запрос("Выбрать Первые 1 
		|т.Ссылка как ВариантГоловногоУбора,
		|Максимум(т.Количество_материалов) как МаксимальноеКоличествоМатериалов
		|Из Справочник.Варианты_головных_уборов.ТабличнаяЧасть1 как т
		|Сгруппировать по т.Ссылка
		|Упорядочить по МаксимальноеКоличествоМатериалов Убыв");
	РезультатВыборка = Запрос.Выполнить().Выбрать();
	Если РезультатВыборка.Следующий() Тогда
		Сообщить("Вариант:"+РезультатВыборка.ВариантГоловногоУбора+", Количество материалов:"+РезультатВыборка.МаксимальноеКоличествоМатериалов); 
	КонецЕсли;
Ответ написан
Комментировать
anthtml
@anthtml
Системный администратор программист радиолюбитель
Сообщить(макс2.Количество_материалов);
Заменить на
Сообщить(макс2);
У Вас макс2 числового типа, а не объект типа Варианты_головных_уборов
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы