Операторы перехода в программном коде: использовать или нет?

Публикация № 1326746 16.11.20

Методология - Рефакторинг и качество кода

качество кода операторы перехода

Рассмотрим ситуации использования операторов перехода Перейти (GoTo), Возврат (Return), Прервать (Break), Продолжить (Continue). Как вы считаете - это дурной тон, нормальная практика или зависит от ситуации?

Этот вопрос появился у нас в процессе обсуждения некоторых технических вопросов и проведения code-review, но мне интересно обсудить его и на данном тематическом ресурсе. Скажу сразу - мнение в нашей команде разделилось.

Со времен «старой школы» существует мнение, что структурное программирование — это хорошо, а любое отступление от него — это плохо. Однако, общение с профессиональными программистами показывает, что использование операторов break, continue, return на практике применяется довольно часто, потому что это удобно и в большинстве случаев делает программу более понятной. Если взять код типовой конфигурации от компании 1С и немного покопаться, то встречаются эти оба подхода вперемешку (предположу, что писали разные люди в разные временные промежутки).

И действительно Дональд Кнут в свое время писал:

«… Настоящая цель программиста состоит в том, чтобы формулировать наши программы таким образом, чтобы их было легко понимать.» 

Давайте рассмотрим примеры использования и не использования этих операторов и сравним.
 

1. Оператор Перейти (GoTo).

 

Это совсем дурной тон и его использовать не будем). Однако интересно было бы услышать ваши мысли, возможно в сообществе еще есть «староверцы».

2. Оператор Возврат (Return).

 

Давайте рассмотрим некоторый виртуальный пример. Задача будет следующая: Требуется написать функцию получения математическое ожидание покупок клиента или средний чек.

 
 Используем оператор возврата 

 

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

 

 

 
Не используем оператор возврата 

 

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

 

 

 

Какие выводы мы можем сделать из двух вышеуказанных примеров?

  • Во втором примере мы теряем локальность — при достаточно длинном тексте процедуры нужно еще посмотреть, не выполняются ли какие-то действия после условного оператора. Да и не совсем понятно, зачем добавлять лишний уровень вложенности. Теперь представьте, что вы проводите анализ кода (code-review), то вам придется время от времени скролить вверх и вниз всю эту простыню кода, чтобы вернуться к оператору условий.
  • Дополнительно во втором примере нам пришлось вводить переменную, в которой хранится результат выполненных операций. Вспоминаем о «Бритве Оккама» и понятии «Не плоди лишних сущностей».
  • Как вы уже догадались, то проблему большого куска кода в обоих случаях мы можем подвергнуть (в принципе должны) рефакторингу и заключить в отдельную функцию.


     
  • В первом случае мы свами можем попасть на никогда не выполняемый код. Обычно про такое должен выдавать предупреждение компилятор.
     
     Пример кода, который никогда не выполняется
    Функция ЭтоТипБулево(Значение) Экспорт
    	
    	Если ТипЗнч(Значение)=Тип("Булево") Тогда
    		Возврат Истина;
    	Иначе
    		Возврат Ложь;
    	КонецЕсли;
    	
    	// сюда мы никогда доходить не будем
    	Сообщить("А сердечник можно делать из дерева! 
    	| Все равно этот код никогда не выполнится...");
    	Возврат Неопределено;
    	
    КонецФункции
  • Удобно использовать оператор "Возврат" в начале функции при выполнении обязательных проверок на корректность входных параметров. В этом случае легко отвязывается задача проверки параметров от всего куска кода процедуры.
     
     Пример обработки выходных параметров

     

    Функция ПолучитьСреднийЧек(Партнер) Экспорт 
    	
    	// I) Проверяем входные параметры
    
    	// уходим если ошибка, обрабатывать не стоит
    	Если НЕ ЗначениеЗаполнено(Партнер) Тогда
    		Возврат новый Структура(Неопределено,"Данные пустые");
    	КонецЕсли;
    
    	// II) Выполняем основную задачу
    	// ...
    	// ...
    	// ...
    
    КонецФункции
    

     

     

3. Оператор Прервать (Break)


Один из самых востребованных операторов, если рассмотреть программирование на C++. В свое время я часто его использовал в связке с Switch и Операторах цикла (For, While). Обратите внимание, что оператор "Прервать" может использоваться и для выхода из бесконечного цикла.
Рассмотрим вариацию типового примера для подключения к клиенту тестирования механизма автоматизированного тестирования от 1С.

 
 Используем оператор прервать 

 

Подключен = Ложь;
ОписаниеОшибкиСоединения = "";
ТестовоеПриложение = Новый ТестируемоеПриложение(,НомерПорта,);

ВремяОкончанияОжидания = ТекущаяДата() + 70;  // 70 секунд ожидаем подключение
Пока Истина Цикл
	
	Попытка
		ТестовоеПриложение.УстановитьСоединение();
		Подключен = Истина;
		Прервать;
	Исключение
		ОписаниеОшибкиСоединения = ОписаниеОшибки();
	КонецПопытки;
	
	Если ТекущаяДата() >= ВремяОкончанияОжидания Тогда		
		Прервать;
	КонецЕсли;
	
КонецЦикла;

 

 

 
 Не используем оператор прервать

 

Подключен = Ложь;
ОписаниеОшибкиСоединения = "";
ТестовоеПриложение = Новый ТестируемоеПриложение(,НомерПорта,);

ВремяОкончанияОжидания = ТекущаяДата() + 70;  // 70 секунд ожидаем подключение
Пока (ТекущаяДата() <= ВремяОкончанияОжидания) И (Подключен=Ложь) Цикл
	
	Попытка
		ТестовоеПриложение.УстановитьСоединение();
		Подключен = Истина;
	Исключение
		ОписаниеОшибкиСоединения = ОписаниеОшибки();
	КонецПопытки;
	
КонецЦикла;

 

Какие отличия мы видим?

  • в первом случае мы последовательно встречаемся с условиями, так проводить анализ значительно проще на мой взгляд
  • во втором случае код внутри процедуры получился значительно меньше и сразу видно условие выхода из цикла
  • Использование "вечных" условий в операторах цикла - это дурной тон для языка 1С Предприятие. 

 

4. Оператор Продолжить (Continue)

 

Оператор "Продолжить" (continue) позволяет сразу перейти в конец тела цикла, пропуская весь код, который находится под ним. Это полезно в тех случаях, когда мы хотим завершить текущую итерацию раньше времени. 

Будьте осторожны при использовании оператора "Продолжить" с циклом "Пока" (while). Поскольку в этих циклах инкремент счетчиков выполняется непосредственно в теле цикла, то использование "Продолжить" может привести к тому, что цикл станет бесконечным!

Рассмотрим задачу - Требуется выполнить предварительную обработку таблицы данных загруженную из Excel.

В таблице хранится наименование контрагента и некоторые дополнительные данные (сумма и т.п.). В рамках обработки будем искать ссылку на контрагента в базе данных, если данные битые, то будем пропускать поиск.

 
 Необдуманное использование оператора продолжить

 

ш=0;

Пока ш<ТаблицаДанных.Количество()-1 Цикл
	
	стр = ТаблицаДанных[ш];
	
	// такая ошибка сделает наш цикл бесконечным
	Если ЭтоБитыеДанные(стр) Тогда
		Продолжить;
	КонецЕсли;
	
	// Обрабатываем данные во внешней процедуре
	НайтиСсылкуКонтрагентаПоНаименованию(стр);

	// Еще много кода пост обработки
	// ...
	// ...
	// ...
	// ...
	
	ш=ш+1;
	
КонецЦикла;

Процедура "НайтиСсылкуПоНаименованию" ищет ссылку контрагента в базе 1С.

Функция "ЭтоБитыеДанные" проверяет наличие "кривой" информации в полях Сумма, КонтрагентНаименование.

 

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

 
 Более правильный вариант

 

ш=0;

Для ш=0 по ш<ТаблицаДанных.Количество()-1 Цикл
	
	стр = ТаблицаДанных[ш];
	
	// такая ошибка сделает наш цикл бесконечным
	Если ЭтоБитыеДанные(стр) Тогда
		Продолжить;
	КонецЕсли;
	
	// Обрабатываем данные во внешней процедуре
	НайтиСсылкуКонтрагентаПоНаименованию(стр);

	// Еще много кода пост обработки
	// ...
	// ...
	// ...
	// ...
	
КонецЦикла;

 

 

Теперь рассмотрим вариант без использования оператора "Продолжить".

 
 Не используем оператор продолжить

 

ш=0;

Пока ш<ТаблицаДанных.Количество()-1 Цикл
	
	стр = ТаблицаДанных[ш];
	
	// такая ошибка сделает наш цикл бесконечным
	Если НЕ ЭтоБитыеДанные(стр) Тогда
	
		// Обрабатываем данные во внешней процедуре
		НайтиСсылкуКонтрагентаПоНаименованию(стр);
		// Еще много кода пост обработки
		// ...
		// ...
		// ...
		// ...
		
	КонецЕсли;
	
	ш=ш+1;
	
КонецЦикла;

 

 

Выводы:

  • В первом случае мы легко можем допустить ошибку, которая приведет к бесконечному циклу (эта ошибка будет "плавающая", т.е. не всегда будет срабатывать). Поэтому лучше выбрать другой оператор цикла.
  • Большой код, рекомендуем выносить рефакторингом.
  • Второй вариант выглядит более логически понятным и "завершенным".

 

5. Операторы прервать и продолжить

 

Многие учебники рекомендуют не использовать операторы "Прервать" (break) и "Продолжить" (continue), поскольку они приводят к произвольному перемещению точки выполнения программы по всему коду, что усложняет понимание и следование логике выполнения такого кода.

Тем не менее, разумное использование операторов "Продолжить" и "Прервать" может улучшить читабельность циклов в программе, уменьшив при этом количество вложенных блоков и необходимость наличия сложной логики выполнения циклов.

Например, рассмотрим следующую задачу: Требуется провести некоторую обработку данных после загрузки из таблицы Excel и еще будет считать баланс. В случае ошибки нужно выдать сообщение оператору о неконсистентности этих данных.

 
 Используем операторы прервать и продолжить

 

Функция ПолучимБаланс(ТаблицаДанных) Экспорт

	Баланс = 0;
	
	// 1. Обрабатываем массив данных с типами элементов: Позиция(Число) ,Выбрана (булево), Контрагент (Справочник), Сумма (число).
	// 2. Количество записей 1 000 000 элементов
	Для каждого стр из ТаблицаДанных Цикл
		
		Если НЕ стр.Выбрана Тогда
			Продолжить;
		КонецЕсли;
		
		// если битая ссылка, то нужно выдать ошибку
		Если ЭтоБитыеДанные(стр)=Истина Тогда
			Баланс=Неопределено;
			Сообщить("Позиция "+стр.Позиция+" битые данные!");
			Прервать;
		КонецЕсли;		
		
		Баланс = Баланс+стр.Сумма;		
			
	КонецЦикла;
	
	Возврат Баланс; 
КонецФункции

Функция "ЭтоБитыеДанные" проверяет наличие "кривой" информации в полях Сумма, Контрагент.

 
 Не используем операторы прервать и продолжить

 

Функция ПолучимБаланс(ТаблицаДанных) Экспорт
	
	Баланс = 0;
	БитыеДанные = Ложь;
	
	// 1. Обрабатываем массив данных с типами элементов: Позиция(Число) ,Выбрана (булево), Контрагент (Справочник), Сумма (число).
	// 2. Количество записей 1 000 000 элементов
	Для каждого стр из ТаблицаДанных Цикл
		
		Если стр.Выбрана Тогда			
			БитыеДанные = ЭтоБитыеДанные(стр);
			Если БитыеДанные =Ложь Тогда
				Баланс = Баланс+стр.Сумма;
			Иначе
				БитыеДанные =Истина;
				Баланс = Неопределено;
				Сообщить("Позиция "+стр.Позиция+" битые данные!");
			КонецЕсли;
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат Баланс;
КонецФункции

 

Код выше требует рефакторинга, т.к. гонять цикл впустую (вдруг битые данные будут сразу со второго элемента) - это "жесть" конечно. Иными словами для следования структурному подходу требуется изменение структуры.

 
 Не используем операторы прервать и продолжить вариант 2

 

Функция ПолучимБаланс(ТаблицаДанных) Экспорт
	
	Баланс = 0;
	ш=0;
	
	// 1. Обрабатываем массив данных с типами элементов: выбрана (булево), Сумма (число).
	// 2. Количество записей 1 000 000 элементов
	Пока ш<ТаблицаДанных.Количество()-1 И ЭтоБитыеДанные(ТаблицаДанных[ш])=Ложь Цикл
		
		Если ТаблицаДанных[ш].Выбрана Тогда
			Баланс = Баланс+ТаблицаДанных[ш].Сумма;
		КонецЕсли;
		
	КонецЦикла;
	
	// если ш меньше размера таблицы, значит мы не дошли до конца без ошибок
	Если ш<ТаблицаДанных.Количество()-1 Тогда
		
		Баланс = Неопределено;
		Сообщить("Позиция "+стр.Позиция+" битые данные!");
		
	КонецЕсли;
	
	Возврат Баланс;
КонецФункции

 

 

Рассмотрим результат сравнения:

  • Не желание использовать операторы переходов вынудило нас во втором случае полностью переписать код
  • Во втором случае потребовалось заводить лишние переменные
  • Во втором случае потребовалось вынести часть логики из цикла в конец функции, что увеличивает объем кода выполняющий решения поставленной задачи
  • В циклах "Для" и "Для каждого" удобно использовать оператор "Продолжить" для быстрого перехода к следующей итерации по результатам условий, если текущая строка не требует обработки.
     
     Пример перехода к следующей итерации в цикле, если не требуется обработка на текущем шаге

     

    // ...
    
    Для каждого стр из ТаблицаДанных Цикл
    		
    	Если НЕ стр.Выбрана Тогда // Переходим сразу к следующей итерации
    		Продолжить;
    	КонецЕсли;
    
        // Далее обрабатываем данные
        // ...
    
    КонецЦикла;
    
    // ...

     

     

Заключение

 

Я считаю, что использование или не использование операторов зависит от ситуации. В некоторых случаях-  это позволяет существенно упростить написание и понимание кода. Однако, в некоторых случаях небрежное или "слепое" использование операторов переходов может привести к нежелательным последствиям. 

  • Операторы "Продолжить" и "Прервать" удобно использовать в циклах "Для" и "Для каждого"
  • Если речь идет про оператор цикла "Пока", то тут лучше стараться не использовать "Продолжить", т.к. в некоторых комбинациях возможно создание бесконечного цикла.
  • Дурной тон в операторах циклов использовать "вечные" условия по типу " Пока Истина Цикл".
  • При использовании оператора "Возврат" надо следить, чтобы не оставалось недостижимого кода.
  • Также возможны случаи написания недостижимого кода с операторами "Продолжить" и "Прервать".
  • Оператор "Возврат" удобно использовать в начале функций при выполнении проверок на консистентность (корректность) входных параметров.
  • Оператор "Перейти" запрещено использовать.
  • Если придерживаться структурного подхода, то следует себя ограничивать в создании вложенности (или "матрешек") с условиями "Если Тогда", так как это затрудняет понимание кода и увеличивает критерий цикломатичности.
  • В процессе разработки (кодирования) всегда выполняем рефакторинг кода и выносим большие блоки в отдельные функции.
  • Используйте в процессе работы анализ качества кода (код-ревью) (По следам код-ревью, Как завести у себя в команде код-ревью. Отвечаем на вопросы)
  • Используйте тестирование и автоматизированное тестирование (Автоматизация тестированияПример создания сценарного UI теста для платформы 1С)

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Steelvan 123 16.11.20 11:04 Сейчас в теме
Во втором примере всегда делаю ЗначениеВозврата в начале функции.
Плюсом это сразу дает понимание, что возвращается из функции.
Плюсом сразу определяешь ЗначениеВозврата по умолчанию, которое всегда вернется, если даже одно условие с кодом изменения не сработает.

Крутку в любом случае по коду делаешь.
Мне для того и дано колесико мышки, чтобы крутку можно было делать удобно, это не аргумент.
PLAstic; user1464234; +2 Ответить
2. ivanov660 2843 16.11.20 11:12 Сейчас в теме
(1) На счет скролла кода:
1. С психологической точки зрения при постоянном переключении туда-сюда больше устаешь и соответственно теряется эффективность.
2. По некоторым рекомендациям проведения код ревью: чем меньше код и более компактный, тем проще проводить эту процедуру.
3. С точки зрения эффективности анализа кода, гораздо проще понять в чем суть:
//..
ВыполнитьДействие1();
ВыполнитьДействие2();
ВыполнитьДействие3();
//..
Процедура ВыполнитьДействие1()
// какая-то обработка
Для каждого ...
КонецПроцедуры
Показать

чем
//..
Для каждого .....
//Условия
// ...
Для каждого ...
//
Для каждого ...
//
Показать


т.е. чем компактней код тем лучше, но не всегда такого можно добиться.
3. PLAstic 274 16.11.20 12:50 Сейчас в теме
(2) Сначала отвечу на это сообщение. Тут нужен здравый смысл. Если процедура длинная, но при выделении её частей в отдельные процедуры приходится передавать целую портянку параметров, то логично, что нужно оставить эту процедуру в покое - на протяжении всего её контекста задействовано множество взаимосвязанных параметров и следование правилу "не более N строк" в данном случае наоборот, затруднит понимание алгоритма.
По поводу же статьи, тут тоже всё логично. Я 15 лет назад первый раз сходил на несколько курсов Арутюнова Сергея из 1УЦ (он и сейчас их ведёт), который помог понять логику разработчиков и увидеть смысл. Конечно, лишние уровни вложенности затрудняют чтение, поэтому и встречаются проверки с возвратом в начале типовых процедур/функций. Полностью согласен с (1), тоже оформляю структуру возврата в начале и использую во всех возвратах. Формат ответа любой функции/процедуры всегда д.б. един. Следует избегать случаев, когда при каких-то условиях мы возвращаем Неопределено, а когда-то структуру. Или один раз у нас структура пустая, а в другой - с набором реквизитов.
4. bulpi 186 16.11.20 14:15 Сейчас в теме
"Оператор "Перейти" запрещено использовать."
Если бы все было именно так, то этого оператора не было в синтаксисе.
Vlad_2008; Perfolenta; brr; +3 1 Ответить
5. ivanov660 2843 16.11.20 14:25 Сейчас в теме
(4) Это правило хорошего тона. Однако, мне встречались реализации на 1С, где довольно часто использовался этот оператор. И выглядел этот кода довольно уныло.
С другой стороны, если взять Ассемблер (или машинные коды), то там как раз в большинстве своем использования операторов перехода и особенно "перейти" (jmp)
6. alexey.kutya 264 16.11.20 14:33 Сейчас в теме
Ни разу не было желания использовать Перейти (GOTO).
Все остальные использую, если это эффективно.
19. teller 23.11.20 06:55 Сейчас в теме
(6) при программировании конечных автоматов логичнее использовать goto,
если вы чего-то не ... то это не значит что это не ... .
Статья из серии "Дейкстру и Вирта не читал , но имею собственное мнение "
7. FesenkoA 55 16.11.20 14:33 Сейчас в теме
Пфффф, у меня по арифметике было "5"!

ш=-1;
Пока ш<ТаблицаДанных.Количество()-1 Цикл

	ш=ш+1;

	стр = ТаблицаДанных[ш];
	
	Если ЭтоБитыеДанные(стр) Тогда
		Продолжить;
	КонецЕсли;

	НайтиСсылкуКонтрагентаПоНаименованию(стр);
КонецЦикла;
Показать
mussolene; +1 Ответить
8. potoyalo 17.11.20 07:17 Сейчас в теме
Выводы гениальны, конечно.. <ОператорName> удобно использовать там, где он уместен.
Не понял, откуда у вас получился вывод, что Оператор "Перейти" использовать запрещено?
Perfolenta; brr; +2 Ответить
9. mussolene 17.11.20 07:26 Сейчас в теме
Прочитал статью по диагонали. НЕ увидел аргументированного вывода по переходу. Он здесь в принципе не раскрыт. Его можно и нужно использовать в условиях когда например тебе нужно выполнить код через Выполнить() и не хочешь чтобы выполнялась громоздкая конструкция в случае когда какая то проверка не выполнилась. По поводу примеров написанных выше скажу только одно. второй пример супер не оптимальный и можно сократить как миниму несколько возвратов, так же разность возвращаемых данных это просто жесть. Когда попробуешь потом возврат обработать еще такую же простыню получишь
brr; Dementor; +2 1 Ответить
10. mussolene 17.11.20 07:33 Сейчас в теме
Функция ПолучитьСреднийЧек(Партнер) Экспорт
	
	СтруктураВозврата = Новый Структура("СреднийЧек,Ошибка",0,"");
	
	Если Не ЗначениеЗаполнено(Партнер) Тогда
		СтруктураВозврата.Ошибка = "Не заполнены данные!!!";
		Возврат СтруктураВозврата;
	КонецЕсли;

	Запрос = новый Запрос;
	Запрос.Текст="ВЫБРАТЬ
	|	СРЕДНЕЕ(РасчетыСКлиентами.Сумма) КАК СреднийЧек
	|ИЗ
	|	РегистрНакопления.РасчетыСКлиентами КАК РасчетыСКлиентами
	|ГДЕ
	|	РасчетыСКлиентами.АналитикаУчетаПоПартнерам.Партнер = &Партнер
	|	И РасчетыСКлиентами.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг
	|	И РасчетыСКлиентами.Сумма <> 0
	|
	|ИМЕЮЩИЕ
	|	НЕ СРЕДНЕЕ(РасчетыСКлиентами.Сумма) ЕСТЬ NULL";
	Запрос.УстановитьПараметр("Партнер",Партнер);
	Результат = Запрос.Выполнить();
	Выборка = Результат.Выбрать();
	
	Если Выборка.Следующий() Тогда
		ЗаполнитьЗначенияСвойств(СтруктураВозврата,Выборка);	
	Иначе
		СтруктураВозврата.Ошибка = "Данные не получены!!!";
	КонецЕсли;
	
	Возврат СтруктураВозврата;
	
КонецФункции
Показать
11. mussolene 17.11.20 07:48 Сейчас в теме
(9) Так же остается вопрос в инициализации переменных постоянно. Вы вкурсе что инициализация переменной это новая ячейка памяти. Представьте что у вас 1 кк пользователей запустили код в котором инициализируется несколько десятков переменных. Вам не хватит памяти нормально обрабатывать данные.

И вообще в чем проблема при использовании операторов не понимаю. Как можно все это говорить??? При определенных условия операторы условного перехода ограничивают потребление памяти и время выполнения определенного кода. Это касается не только 1С.

По поводу выводов в конце статьи. Согласен только с тем что код нужно писать оптимально по некоторым пунктам.
12. Rais96 17.11.20 07:50 Сейчас в теме
Всегда использую оператор Перейти, если нужен выход из сложного или вложенного цикла. Код чище и главное понятнее. Мнимый запрет на goto, сформирован вначале распространения структурного программирования, потом ввели break, continue, которые по сути те же goto. А методика преподавания не поменялась, потому и в промышленное программирование приходят с аксиомой что goto запрещено. Мы программируем не для красоты, а чтобы было понятнее и проще разобраться в коде, а что при этом нарушаются какие-то понятия программирования, так пусть теоретики подстраивают свои теории под практику.
Drivingblind; itoptimum; brr; Perfolenta; Dementor; mussolene; +6 1 Ответить
14. Perfolenta 195 17.11.20 13:52 Сейчас в теме
(12) поддерживаю, оператор Перейти вполне полезен в некоторых ситуациях и ни чем не хуже любых других операторов...
Он был назначен виновником всех бед тогда, когда блочных операторов ещё не было и даже процедур в современном понимании еще не было... тогда использование Goto было безальтернативным и превращало код во "взрыв на макаронной фабрике"...
но те времена давным-давно прошли...
Сегодня, если в методе есть один-два оператора Перейти код не превращается в сложный для чтения и не повышает вероятность ошибок...
Если у вас стоит цель запутать код, то вы и без оператора Перейти справитесь на отлично, а если мозги на месте, то и оператор Перейти будет полезен...
itoptimum; +1 Ответить
15. ivanov660 2843 17.11.20 17:12 Сейчас в теме
(14) Если ВЫ действительно говорите что использование оператора Goto оправдано в текущий момент и вы его используете, то для меня это звучи ужасно.
Если про использование других операторов прервать, возврат, то нормальная практика.
16. Perfolenta 195 17.11.20 23:17 Сейчас в теме
(15) есть яды, которыми лечат... молотком не надо стучать по голове...
неужели вы пугаетесь увидев оператор Перейти, не понимаете, что происходит и вынуждены тратить лишнее время?
мне кажется, что нет...
Производительность кода он тоже не снижает, к ошибкам не приводит... в чем проблема?
Зато он удобен при выходе из нескольких вложенных циклов,
годится для перехода в конец метода для выполнения завершающих действий...
Такие случаи сами по себе редки, но в них он смотрится хорошо и удобно, так чего его не использовать? Только из-за чьих-то предубеждений (смысл которых потерялся в прошлом веке)?
pm74; Award; +2 Ответить
17. nporrep 50 18.11.20 22:21 Сейчас в теме
(15) Рекомендации по ограничению (не запрету!) использования безусловного перехода (jmp) в пользу передачи управления (call/ret) стали актуальным при смещении парадигмы от "линейного" программирования к блочному, дабы не запутывать спагетти.

Но сейчас, в эпоху асинхронной многопоточности, goto используется даже в ультрасовременном golang (микросервисы-каналы-горутины-ралли и вот это вот всё), а использование приема перехода к метке особенно актуально при кодогенерации, когда исполняемый код программно создается по широкому набору условий, и неизвестен заранее...
18. makfromkz 14 19.11.20 07:31 Сейчас в теме
(12) Также поддерживаю, в Фортан4 был оператор вычисляемый Goto
Попробуйте его реализовать по методике структурного программирования, если все метки находятся в линейном алгоритме.

Я когда писал на Си программу эмуляции мультиплексного канала, тоже хотел следовать "структурности", но увидев накладные расходы "структурности", плюнул и вернулся к goto
13. mussolene 17.11.20 08:06 Сейчас в теме
В примерах про продолжить (4) просто гениальное использование циклов от аля ХЗ кого. Почему нельзя нормально итератором пройти и цикл не будет бесконечным

Для Каждого Стр Из ТаблицаДанных Цикл
     Если ЭтоБИтыеДанные(Стр) Тогда
           Продолжжить
     КонецЕсли;
     //Обработка вашего кода

КонецЦикла


Очень сложная конструкция я вам скажу(нет)
20. Hans 1 01.12.20 20:50 Сейчас в теме
Написал бы в примерах кода "Правильно", "Неправильно". Я так предполагаю что использование оператора Возврат посреди функции это плохо. Возврат должен быть только в начале или конце.
21. ivanov660 2843 02.12.20 12:10 Сейчас в теме
(20)
1. Там где не правильно и могут быть ошибки я отметил
2. Оба подхода можно применять. Это две "методологии": структурный (без операторов перехода) и "прогрессивный" (используем операторы перехода там где удобно).
3. Вопрос родился из-за существующих двух разных школ при разработке кода на 1С.
22. Hans 1 02.12.20 13:09 Сейчас в теме
(21) Про школы отдельную статью. Что за школы?
Оставьте свое сообщение

См. также

Смотрим запросы 1С через Microsoft SQL Profiler по следам ошибок разработчиков, приводящих к проблемам производительности

Производительность и оптимизация (HighLoad) Рефакторинг и качество кода Технологический журнал v8 Бесплатно (free)

Расскажем про инструменты, рассмотрим планы запросов, увидим, как отслеживать и бороться с проблемами производительности на боевой базе.

07.09.2021    3374    ivanov660    22    

Распространенные ошибки разработчиков, приводящие к проблемам производительности

Производительность и оптимизация (HighLoad) Рефакторинг и качество кода v8 Бесплатно (free)

Рассмотрим примеры ошибок, анализ, исправление и мероприятия по недопущению подобного в будущем. Всего будет 18 примеров.

02.08.2021    8699    ivanov660    77    

Антипаттерны программирования в 1С

Практика программирования Рефакторинг и качество кода v8 Бесплатно (free)

Поговорим про плохой стиль программирования и рассмотрим 17 часто встречающихся антипаттернов.

19.07.2021    9809    ivanov660    121    

Чек-листы для проведения Code Review

Рефакторинг и качество кода v8 1cv8.cf 1С:Франчайзи, автоматизация бизнеса Бесплатно (free)

В данной статье будут приведены два чек-листа (основной и для проверки архитектурных решений). По данным чек-листам программист любой квалификации может проверить свой код и код других разработчиков.

17.05.2021    7831    Alexsandr_Retunskiy    99    

Ускорение расчета себестоимости УПП 1.3 в несколько раз

Рефакторинг и качество кода Закрытие периода v8 УПП1 БУ УУ Бесплатно (free)

Как определить причину медленного расчёта себестоимости в УПП 1.3, один из вариантов поиска проблем производительности с помощью инструментов 1С и ускорения расчёта средствами встроенного языка

02.02.2021    3427    RPGrigorev    19    

Реальный кейс по внедрению CodeReview

Рефакторинг и качество кода v8 1cv8.cf Бесплатно (free)

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

20.01.2021    1873    Alexsandr_Retunskiy    3    

Чистый кот (Clean cat)

Рефакторинг и качество кода v8 1cv8.cf Бесплатно (free)

От автора легендарного бестселлера "Совершенный кот".

04.11.2020    1875    vasilev2015    25    

Доработайте это "немедленно", или как уменьшить доработки конфигурации

Рефакторинг и качество кода v8 Россия Бесплатно (free)

Доработки конфигурации - необходимое зло. Автор предлагает несколько простых подходов и приемов, позволяющих хотя бы немного, но оптимизировать объем доработок конфигурации, упростить их, и облегчить дальнейшие доработки и обновления конфигурации. Все примеры и подходы взяты автором из реальной жизни и основаны на собственных наблюдениях.

25.09.2020    4153    Богатырев Артур    24    

Метод борьбы с большим количеством комментариев в коде

Практика программирования Рефакторинг и качество кода v8 1cv8.cf Бесплатно (free)

Решил поделиться нашим способом борьбы с сильно закомментированным кодом.

08.09.2020    1527    tambu    9    

Как поставить качество кода на поток и при этом не разориться? Какие шаги стоит сделать уже завтра, чтобы повысить планку качества?

Рефакторинг и качество кода v8 Бесплатно (free)

Наличие в 1С-решениях некачественного кода мешает их поддержке и эффективному развитию. Как добиться соблюдения стандартов разработки при написании кода и внедрить бюджетный Code Review с помощью инструментария на основе АПК (Автоматизированной проверки конфигураций) на конференции Infostart Event 2019 Inception рассказал технический руководитель компании Бизнес Лоджик Иван Козлов.

22.06.2020    4049    kozlov.alians    1    

Молчание "best practices": тестовые и эталонные данные, структура и связность, падения и новая функциональность, и другие неудобные вопросы к сценарному тестированию

Рефакторинг и качество кода Сценарное тестирование v8 Бесплатно (free)

Непонимание некоторых базовых вопросов мешает программистам начать применять инструменты тестирования в процессе разработки для 1С. Как разобраться в терминологии и интегрировать процесс тестирования в разработку 1С-решений на конференции Infostart Event 2019 Inception рассказал руководитель отдела разработки компании C.T.Consultants Решитко Дмитрий.

29.05.2020    5190    grumagargler    14    

Рефакторинг в редакторе модулей

Рефакторинг и качество кода v8 1cv8.cf Бесплатно (free)

Для тех, кто не пользуется Ctrl+Alt+R. “Контролируемый процесс улучшения кода без написания новой функциональности”, “Равносильное преобразование алгоритмов” и т.п в данной статье НЕ рассматриваются. Тема статьи: замечательные команды из подменю Рефакторинг контекстного меню редактора модулей в конфигураторе. В статье описано, как команды из подменю Рефакторинг помогают при написании кода

10.03.2020    4656    pparshin    5    

Качество кода: Поведенческие паттерны проектирования

Рефакторинг и качество кода v8 Бесплатно (free)

Поговорим про применение паттернов проектирования в разработке на 1С.

03.03.2020    9115    ivanov660    0    

Боремся с запросами в циклах. Мой опыт рефакторинга запросов

Рефакторинг и качество кода v8::Запросы 1cv8.cf Бесплатно (free)

В текущей публикации я предлагаю вам несколько простых примеров с решениями, в которых будет представлено решение "единым запросом", без использования запросов в цикле.

02.03.2020    9184    aximo    55    

Стабильность превыше всего

Рефакторинг и качество кода v8 Бесплатно (free)

Странная заметка о поддержании стабильности в условиях интенсивного изменения конфигурации.

07.11.2019    10202    YPermitin    40    

Оценка скорости кода. Сложность алгоритма

Практика программирования Рефакторинг и качество кода v8 1cv8.cf Бесплатно (free)

Эта тема одной из первых всплывает на собеседовании программистов языков вроде Java и C, но она почти неизвестна в "мире 1С". Поговорим о вычислительной сложности алгоритмов.

07.10.2019    6663    m-rv    12    

Управление качеством кода

Математика и алгоритмы Рефакторинг и качество кода SonarQube EDT v8 Бесплатно (free)

О SonarQube, АПК, EDT. Какие преимущества дает их использование. Для каких команд подходит.

22.07.2019    19354    Stepa86    40    

По следам код-ревью

Рефакторинг и качество кода v8 Бесплатно (free)

Приведу примеры с картинками и небольшим пояснением по вопросам, связанным с код-ревью (обзором кода).

09.07.2019    14501    ivanov660    111    

Что такое рефакторинг и в чем его цели

Практика программирования Рефакторинг и качество кода v8 Бесплатно (free)

Что такое рефакторинг, и в каких случаях им стоит заниматься? Евгений Шумилов дает ответы на эти вопросы, а также рассказывает о признаках хорошего и плохого кода. Кроме того, в статье приведены основные проблемы рефакторинга и способы их решения.

30.10.2018    13639    eu_genij    34    

Мастер-класс от Poppy (практикум по рефакторингу)

Практика программирования Рефакторинг и качество кода v8 1cv8.cf Россия Бесплатно (free)

Попался на глаза код неопытного программиста. Не смогла пройти мимо, захотелось выполнить рефактроинг. Вот что из этого получилось.

04.11.2008    18931    poppy    33