Рефакторинг без тормозов (десять приемов в одной задаче)
Разработка - Рефакторинг и качество кода
Файлы
ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.
Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний
Оформите подписку на компанию для решения рабочих задач
Оформить подписку и скачать решение со скидкойВы можете заказать платную доработку или адаптацию этой разработки под вашу конфигурацию на «Бирже заказов».
- 0% комиссии — оплата напрямую исполнителю;
- Исполнители любого масштаба — от отдельных специалистов до команд под проект;
- Прямой обмен контактами между заказчиком и исполнителем;
- Безопасная сделка — при необходимости;
- Рейтинги, кейсы и прозрачная система откликов.
Функция, используемая для примера, решает задачу разбиения периода времени, заданного начальной и конечной датой, на отрезки, принадлежащие различным месяцам. Пусть в исходном варианте вид функции будет таким -ВАРИАНТ0:
Функция РазбитьПериод0(ДатаС, ДатаПо) Экспорт
МассивПериодов = Новый Массив;
Дата1 = ДатаС;
Дата2 = ДобавитьМесяц(НачалоМесяца(Дата1), 1);
Пока Истина Цикл
Дата3 = Дата2 - 1;
Если Дата3 > ДатаПо Тогда
Дата3 = ДатаПо
КонецЕсли;
ЗаписьПериода = Новый Структура;
ЗаписьПериода.Вставить("НачалоПериода", Дата1);
ЗаписьПериода.Вставить("КонецПериода", Дата3);
МассивПериодов.Добавить(ЗаписьПериода);
Если Дата3 = ДатаПо Тогда
Прервать
КонецЕсли;
Дата1 = Дата2;
Дата2 = ДобавитьМесяц(Дата1, 1)
КонецЦикла;
Возврат МассивПериодов
КонецФункции
Здесь можно сделать следующее
-
Можно не выполнять присваивания "Дата1 = ДатаС". Вместо этого достаточно использовать сам параметр «ДатаС» как переменную, а чтобы после выполнения функции его значение не оказалось «испорченным», перед ним в заголовке функции нужно использовать лексему «Знач». Это означает, что параметр передается не «по ссылке», когда используется ранее выделенная переменной память, а «по значению», когда создается новый экземпляр переменной.
-
Можно сэкономить на придумывании осмысленного названия переменной, предназначенной для вычисляемого значения функции. Если результат функции строится в ходе ее выполнения и должен быть как-то заранее назван, лучше не выдумывать нового термина, так как у функции уже есть имя, а назвать результат выполнения функции в процессе его вычисления просто «Результат» или «Ответ».
-
Последовательность операторов «Дата3 = Дата2 - 1;Если Дата3 > ДатаПо Тогда Дата3 = ДатаПо КонецЕсли» это всего лишь присвоение значения переменной «Дата3» с учетом ограничения ее значения сверху значением переменной «ДатаПо». Эта задача проще и нагляднее решается с помощью функции «Мин». То есть, если результат выражения должен учесть ограничения на результат сверху или снизу, следует использовать функцию минимум или максимум, которые читаются легче и пишутся короче, чем условный оператор «если» или условный оператор с вопросом.
-
Конструктор структуры позволяет сразу проинициализировать ее элементы, поэтому вставку элементов можно сократить. Для создания структуры и инициализации ее полей можно пользоваться соответствующей формой конструктора, куда сразу передать имена полей через запятую и значения полей. Так создаются структуры периодов, добавляемых в массив.
-
Можно не создавать переменную для ссылки на создаваемую структуру. Так как она будет использована лишь однажды – в следующей строке программы. Вместо этого результат можно сразу записать на место его использования. Тогда не нужно будет «вымучивать» названия лишних переменных. Исключением являются случаи, когда промежуточный результат требует пояснения или контроля в процессе отладки. В нашем случае строка и без этого легко читается: в массив-результат добавляется новая структура из полей «НачалоПериода», «КонецПериода», имеющих соответствующие значения.
В результате функция оказывается приведенной к виду ВАРИАНТ1:
Функция РазбитьПериод1(Знач ДатаС, ДатаПо) Экспорт
Ответ = Новый Массив;
Дата2 = ДобавитьМесяц(НачалоМесяца(ДатаС), 1);
Пока Истина Цикл
Дата3 = Мин(Дата2 - 1, ДатаПо);
Ответ.Добавить(Новый Структура("НачалоПериода, КонецПериода", ДатаС, Дата3));
Если Дата3 = ДатаПо Тогда
Прервать
КонецЕсли;
ДатаС = Дата2;
Дата2 = ДобавитьМесяц(ДатаС, 1)
КонецЦикла;
Возврат Ответ
КонецФункции
Анализируя эту запись, можно придти к выводу, что переменные «ДатаС», «Дата2» и «Дата3» связаны простой зависимостью. "ДатаС" – это начало периода или начало текущего месяца, "Дата2" – это начало следующего, а "Дата3" – конец текущего месяца. Выполним подстановку и
-
Избавимся от лишних, то есть связанных простой зависимостью, переменных.
В результате этого получаем ВАРИАНТ2:
Функция РазбитьПериод2(Знач ДатаС, ДатаПо) Экспорт
Ответ = Новый Массив;
Пока ДатаС < = ДатаПо Цикл
Ответ.Добавить(Новый Структура("НачалоПериода, КонецПериода", ДатаС, Мин(КонецМесяца(ДатаС), ДатаПо)));
ДатаС = КонецМесяца(ДатаС) + 1
КонецЦикла;
Возврат Ответ
КонецФункции
Внимание: Из-за того, что знак "меньше или равно" в тексте функции неправильно отрабатывается при редактировании статьи на этом сайте, в него добавлен пробел!
Похожий вариант уже публиковался на Инфостарте [?], вот он - ВАРИАНТ3:
Функция РазбитьПериод3(ДатаС, ДатаПО) Экспорт
Ответ=Новый Массив;
Мес=НачалоМесяца(ДатаС);
Пока Мес< =НачалоМесяца(ДатаПО) Цикл
Период=Новый Структура;
Период.Вставить("НачалоПериода", ?(НачалоМесяца(ДатаС)=Мес,ДатаС,Мес));
Период.Вставить("КонецПериода", ?(НачалоМесяца(ДатаПО)=Мес,ДатаПО,КонецМесяца(Мес)));
Ответ.Добавить(Период);
Мес=ДобавитьМесяц(Мес,1);
КонецЦикла;
Возврат Ответ;
КонецФункции
Здесь само собой напрашивается применение приемов 3, 4 и 5, в результате чего получается более красивый и компактный ВАРИАНТ4
Функция РазбитьПериод4(ДатаС, ДатаПО) Экспорт
Ответ = Новый Массив;
Мес = НачалоМесяца(ДатаС);
Пока Мес < = ДатаПО Цикл
Ответ.Добавить(Новый Структура("НачалоПериода, КонецПериода", Макс(ДатаС,Мес), Мин(ДатаПО,КонецМесяца(Мес))));
Мес = ДобавитьМесяц(Мес, 1)
КонецЦикла;
Возврат Ответ
КонецФункции
В общем, результат в варианте 2 уже можно было бы принять, однако функция «Мин» смотрится инородно. Возможно, это от того, что она срабатывает лишь однажды – на самом последнем периоде. И если периодов много – эти сравнения оказываются лишними. Также, кажется, что можно избавиться от переменной «ДатаС», которая всегда на единицу больше конца периода, только что записанного в массив. А если попробовать сначала записать в массив исходный интервал, а затем при необходимости делить его на две записи, выделяя последний месяц в следующую запись? Алгоритм уместился в одном предложении. Возможно, и его запись окажется понятнее и проще?
Чтобы при этом не приходилось затем удалять записи, если интервал «отрицательный», выполним в этом случае обмен «ДатаС» и «ДатаПо». Здесь повторим прием 3 и обойдемся без условных операторов: началом периода будем считать минимум, а концом – максимум значений этих переменных. С точки зрения пользователя функции, это будет удобнее: программисту при записи вызова функции не нужно будет помнить, какую дату записывать первой – меньшую или большую, период можно будет задать и так и так. Функция станет более «робастной», то есть станет лучше защищена от ошибок в исходных данных. Конечно, это будет иметь свою цену - так отсекается возможность использования функции для контроля, что «ДатаС» меньше «ДатаПо». В результате получаем следующий ВАРИАНТ5:
Функция РазбитьПериод5(ДатаС, ДатаПо) Экспорт
Ответ = Новый Массив;
Ответ.Добавить(Новый Структура("НачалоПериода, КонецПериода", Мин(ДатаС, ДатаПо), Макс(ДатаС, ДатаПо)));
Пока НачалоМесяца(Ответ[0]["НачалоПериода"]) < НачалоМесяца(Ответ[0]["КонецПериода"]) Цикл
Ответ.Вставить(1, Новый Структура("НачалоПериода, КонецПериода", НачалоМесяца(Ответ[0]["КонецПериода"]), Ответ[0]["КонецПериода"]));
Ответ[0]["КонецПериода"] = Ответ[1]["НачалоПериода"] - 1
КонецЦикла;
Возврат Ответ
КонецФункции
Рассматривая этот результат, можно заметить, что текст «НачалоПериода», «КонецПериода», "Ответ[0]" часто повторяется. Поэтому,
-
Если запомнить повторяющиеся константы и сложные ссылки в переменных с короткими названиями, длину кода можно сократить.
-
При этом некоторые переменные, обозначающие в данной функции константы, лучше вообще сделать параметрами функции и проинициализировать в описании параметров. В данном случае это касается названия полей структуры. Кроме сокращения записи, это придает функции дополнительную гибкость, расширяя варианты ее использования.
Прием 8 заслуживает демонстрации еще одним примером. Вот функция для получения количества элементов массива, равных образцу, с использованием приема 8.
Функция Сколько(Массив, Образец, Ответ = 0) Экспорт
Для Каждого Элемент Из Массив Цикл
Ответ = Ответ + Число(Элемент = Образец)
КонецЦикла;
Возврат Ответ
КонецФункции
Если массив «Слова» хранит слова программного кода некоторой функции, то выражение
Сколько(Слова, «Цикл», Сколько(Слова, «Тогда», 1))
рассчитает показатель цикломатической сложности функции.
Возвращаясь к исходной функции, применение приемов 7 и 8 дает следующий результат - ВАРИАНТ6:
Функция РазбитьПериод6(ДатаС, ДатаПо, Поле1 = "НачалоПериода", Поле2 = "КонецПериода") Экспорт
Ответ = Новый Массив;
Э = Новый Структура(Поле1 + "," + Поле2, Мин(ДатаС, ДатаПо), Макс(ДатаС, ДатаПо));
Ответ.Добавить(Э);
Пока НачалоМесяца(Э[Поле1]) < НачалоМесяца(Э[Поле2]) Цикл
Ответ.Вставить(1, Новый Структура(Поле1 + "," + Поле2, НачалоМесяца(Э[Поле2]), Э[Поле2]));
Э[Поле2] = Ответ[1][Поле1] - 1
КонецЦикла;
Возврат Ответ
КонецФункции
Рассматривая текущий вариант функции, можно заметить повтор в четырех местах названия функции «НачалоМесяца». Если это название разделить на два слова и сделать второе из них параметром функции, то она станет более универсальной, сможет выполнять разбивку на «Минуты», «Часа», «Дни», «Недели», «Месяца», «Квартала», «Года» (по понятным причинам придется смириться с некоторым диссонансом в произношении названий периодов). Для этого нам понадобится функция «Выполнить», которая воспринимает код как строку и выполняет его. В исходном коде название функции заменяется на «_», то есть «впишите что хотите», а перед выполнением туда вписывается нужный интервал заменой подстроки. В данном случае применяется наиболее спорный, ухудшающий понимание программы, прием
-
Универсализации кода с использованием оператора «Выполнить». Этот прием следует применять с осторожностью.
Получаем следующий ВАРИАНТ7:
Функция РазбитьПериод7(ДатаС, ДатаПо, НаЧто = "Месяца", Поле1 = "НачалоПериода", Поле2 = "КонецПериода") Экспорт
М = Новый Массив;
Э = Новый Структура(Поле1 + "," + Поле2, Мин(ДатаС, ДатаПо), Макс(ДатаС, ДатаПо));
М.Добавить(Э);
Выполнить(СтрЗаменить(
"Пока _(Э[Поле1])< _(Э[Поле2])Цикл М.Вставить(1,Новый Структура(Поле1+"",""+Поле2,_(Э[Поле2]),Э[Поле2]));Э[Поле2]=М[1][Поле1]-1 КонецЦикла"
, "_", "Начало" + НаЧто));
Возврат М
КонецФункции
Переменная «Ответ» заменена однобуквенной переменной «М» для сокращения длины строковой константы, содержащей шаблонизированный код.
Оглядев результат, видим, что в последнем варианте совершенно потеряна простота и понятность кода, которая ранее оправдывала менее компактную запись функции в варианте 5. Поэтому вернемся к варианту 2 и применим к нему приемы 7, 8 и 9. Здесь мы используем прием
-
Сохранение промежуточных вариантов улучшения кода и возврат к ним из тупиковых ветвей процесса рефакторинга.
В итоге получили следующую универсальную функцию, решающую поставленную задачу (знак "_" заменен словом "Край", что обеспечивает читабельность функции внутри строки ), ВАРИАНТ8:
Функция РазбитьПериод8(Знач А, Б, Чего = "Месяца", Поля = "НачалоПериода, КонецПериода") Экспорт
М = Новый Массив;
Выполнить(СтрЗаменить("Пока А< =Б Цикл М.Добавить(Новый Структура(Поля,А,Мин(Край(А),Б)));А=Край(А)+1 КонецЦикла", "Край", "Конец" + Чего));
Возврат М
КонецФункции
Можно предложить еще дальше и переписать функцию на английский. Получим последний, десятый ВАРИАНТ9
Function РазбитьПериод9(Val A, B, What = "Месяца", Fields = "НачалоПериода, КонецПериода") Export
M = New Array;
Execute(StrReplace("While A<=B Do M.Add(New Structure(Fields,A,Min(Edge(A),B)));A=Edge(A)+1 EndDo", "Edge", "Конец" + What));
Return M
EndFunction
В прилагаемой к статье обработке приведены все вышеописанные функции с возможностью их тестирования.
Нужно сказать, что улучшение кода – процесс, результат которого не всегда можно оценить однозначно. Объективная составляющая оценок представлена метриками кода. Значения метрик компактности и цикломатической сложности [Анализ цикломатической сложности кода] для всех промежуточных вариантов рассматриваемой функции приведены в таблице.
| Номер варианта | Число строк | Число знаков | Цикломатическая сложность | Произвольный период |
| 0 | 21 | 494 | 4 | Нет |
| 1 | 14 | 348 | 3 | Нет |
| 2 | 8 | 255 | 2 | Нет |
| 3 | 12 | 385 | 4 | Нет |
| 4 | 9 | 279 | 2 | Нет |
| 5 | 9 | 469 | 2 | Нет |
| 6 | 10 | 399 | 2 | Нет |
| 7 | 9 | 407 | 1 | Да |
| 8 | 5 | 263 | 1 | Да |
| 9 | 5 | 242 | 1 | Yes! |
Субъективная составляющая оценок отражает простоту и понятность кода. Применяя все перечисленные приемы исключительно в погоне за компактностью, можно пропустить момент утраты понятности кода, то есть важно вовремя затормозить. Но когда? Наверное, каждый должен решать сам. В конце концов, кто-то считает, что «тормоза придумали трусы», а кто-то: «тише едешь – дальше будешь».
Вступайте в нашу телеграмм-группу Инфостарт
См. также
Нейросети Рефакторинг и качество кода Запросы Разработчик 1С 8.3 Абонемент ($m)
Нейросеть написала запрос или процедуру для вашей базы 1С, и непонятно, все ли имена в нём настоящие. Обработка компилирует текст без выполнения, сверяет его с метаданными этой базы и к каждой ошибке пишет настоящее имя, например ВНаличииОстаток вместо выдуманного КоличествоОстаток. Список ошибок с подсказками одной кнопкой копируется обратно в чат с моделью.
10 стартмани
02.11.2026 347 1 nedomolkov.ivan 1
Рефакторинг и качество кода Разработчик 1С:Предприятие 8 Россия Бесплатно (free)
Одна проверка в обработчике кнопки может выглядеть достаточной, пока ту же операцию не вызовут из другого места. На примере управляемой формы разберём, почему так происходит, как разместить проверку в общей серверной функции и чем отличается удобная проверка ввода от обязательного условия выполнения операции.
29.10.2026 371 YA_777378709 0
Рефакторинг и качество кода Разработчик Бесплатно (free)
Рассказываем, почему качественный код – это не техническая прихоть, а актив, который помогает бизнесу быстрее адаптироваться к изменениям и запускать новые фичи без бесконечного преодоления техдолга. Показываем, как объяснить бизнесу ценность рефакторинга через понятные признаки: замедление разработки, неточные оценки, страх перед legacy и хрупкость системы. Разбираем, почему неправильный рефакторинг может быть дороже его отсутствия, какие анти-паттерны ломают процесс и как не превратить улучшения в бесконечную переделку ради переделки. Объясняем, как сделать рефакторинг частью культуры команды: договориться с бизнесом, научить разработчиков видеть проблемные места, закрепить правила и поддерживать улучшения на уровне тимлидов, архитекторов и всей команды.
28.10.2026 482 Pavel791 0
Рефакторинг и качество кода HighLoad оптимизация Системный администратор Разработчик Стажер 1С 8.3 Абонемент ($m)
Если к HTTP-сервису 1С обращаются сразу несколько программ, сколько запросов в секунду он успеет обработать? Я опубликовала простой HTTP-сервис на нашей "подопытной" конфигурации «Нано-УТ» (файловая база, Apache, без прав администратора) и нагрузила его скриптом на Python. Ответ: около 15-16 запросов в секунду, сколько бы клиентов ни обращалось одновременно. Запросы ждут своей очереди, и при 32 клиентах ответ приходит через 2 секунды вместо 64 мс. Заодно разобрала скрипт из первого варианта статьи: он «проверял» сервер, который отвечал по одному, и считал ошибки вместе с успешными ответами. В архиве исправленный скрипт, учебный сервер, HTTP-сервис для 1С и инструкция по запуску.
1 стартмани
23.10.2026 516 Ninel_S 3
Рефакторинг и качество кода Разработчик 1С 8.3 Абонемент ($m)
Запустили Analyzer 1C 2.7.65 на промышленной конфигурации (596 модулей, 13 669 функций) и исследовали перегруженные функции (до 1887 строк), циклические зависимости и экран «Циклы» (кольцо из 64 модулей). Разобрали, почему популярные метрики (McCabe, связность) не представлены в продукте вендора, и составили пошаговый план разделения модуля. Привели проверенный платформой 8.3.27 пример до и после рефакторинга и выявили скрытую ловушку загрузки модулей с точкой в имени.
9 стартмани
19.10.2026 452 Ninel_S 2
Рефакторинг и качество кода EDT СКД Разработчик 1С 8.3 1С 8.5 1С:Бухгалтерия 3.0 Бесплатно (free)
Одиннадцать граблей схем компоновки, которые не видно в конструкторе и не ловит EDT, на реальных отчетах БП КОРП. Формат числа задается в двух местах, и условное оформление варианта перебивает формат поля. Ресурс складывает штуки с часами, и помогает выражение «только когда единица одна». Ресурс пуст в детальных записях, параметр не появляется в шапке без userSettingID, valueListAllowed ломает границы периода, Остатки и СрезПоследних с параметром периода падают с «Несоответствием типов», title без xsi:type дает «Исключение XDTO» при загрузке. В конце код проверки схемы из файла до обновления базы, сводная таблица и чеклист.
16.10.2026 519 Konstmax13 2
Инструментарий разработчика Нейросети Рефакторинг и качество кода EDT Разработчик 1С 8.3 1С 8.5 1С:Бухгалтерия 3.0 Бесплатно (free)
Как ИИ-агент (Claude Code) работает в живом EDT-проекте 1С:Бухгалтерии КОРП 3.0: из чего собрать стенд с MCP-сервером для EDT, как ставить задачи агенту, где он ломает проект и какие проверки это ловят. Реальные случаи: рукописные метаданные, ронявшие конфигуратор; четыре дня зависшего обновления из-за порядка блоков в Rights.rights; ошибки, которые EDT пропускает, а платформа нет; сплошная сверка вместо «вроде работает». В приложении шаблон CLAUDE.md, шаблон правила, чеклист перед обновлением базы и скрипты проверки ролей и схем СКД.
15.10.2026 3462 Konstmax13 11
Рефакторинг и качество кода Тестирование QA Разработчик 1С 8.3 Абонемент ($m)
Инженерный анализ влияния (Impact Analysis) при изменении общего метода в 1С:Предприятии: почему штатный поиск ссылок скрывает 99% зависимостей и как обратный обход графа вызовов выявляет 370 скрытых потребителей на глубине 3 уровней. В статье — верификация сквозной цепочки обмена с маркетплейсом; в архиве-компаньоне — автономный BFS-анализатор на Python, слепки графа и план регрессионного тестирования.
1 стартмани
12.10.2026 321 Ninel_S 0
Экономия букв/строк в коде - не есть рефакторинг.
Читабельность, возможность отладки определенно ухудшаются.
(1)
И слава богу.
Обратил внимание только сейчас на ваше имя.
Хотя на этой недели с ребятами ознакомились с "батерфляем". Очень достойно.
Голосую за Вариант 6.
Выполнить() - это не безопасно и имеет смысл применять в очень ограниченных случаях.
Дожимать рефакторинг разбития периода до Выполнить() - это уже не перфекционизм, а полудикий трешь.
(36) Что касается использования Запроса для решения этой задачи - это не обосновано. А если надо все выполнить на клиенте? Будете сервер вызывать? А вот ildarovich не будет! Он может свою функцию вставить в общий модуль и задать ему свойства "клиент" и "сервер". И спокойно вызывать ее и с клиента и с сервера, когда потребуется.
Сам разность дат вычислял с применением запроса. Пока не заморочился с клиент серверной архитектурой.
Так что не прячтесь за цитированием вырванных из контекста отрывков из Википедии, а объясните толком, конкретно, чем Вам не нравится вариант 2, например, или вариант 5. Или с каким приемам из 1-10 Вы не согласны.
Данный "рефакторинг" увеличивает время разработки, ухудшает читабельность, увеличивает трудоемкость по внесению изменений сторонним разработчиком, усложняет отладку, делает невозможным подробное комментирование.
Не забывайте, мы все таки пишем бизнес-приложение, а не компилированный экземпляр ускоспециализированной программы. Если бизнес-приложение не развивается, это значит, что оно не используется.
Функция РазбитьПериод8(Знач А, Б, НаЧто = "Месяца", Поля = "НачалоПериода, КонецПериода") Экспорт
М = Новый Массив;
Выполнить(СтрЗаменить("Пока А< =Б Цикл М.Добавить(Новый Структура(Поля,А,Мин(_(А),Б)));А=_(А)+1 КонецЦикла", "_", "Конец" + НаЧто));
Возврат М
КонецФункции
А теперь просто добавьте сюда функционал, дающий возможность, при желании, исключить из периодов выходные и праздничные дни.
Перфекционизм это хорошо, особенно, когда за него платит заказчик.
Впрочем, на эту тему уже исписаны груды бумаги. Вот, например: "Раньше я думал, что системы становятся более гибкими благодаря тому, что в них добавляется новый код. Однако сейчас я пришел к выводу, что системы становятся более гибкими потому, что из них удаляют лишний код. Пространство вокруг кода обладает значительно большим потенциалом, чем сам код" (Майкл Федерс). "Добавить код в систему значительно проще, чем убрать оттуда код. Рефакторинг позволяет делать вам код настолько простым, насколько это возможно, благодаря этому вы можете сконцентрироваться на добавлении в код новых возможностей" (Кен Ауэр, Рой Миллер).
А Вы сами практикуете рефакторинг? Как Вы это делаете? Приведите пример хорошо отрефакторенной, с Вашей точки зрения функции!
Вы прицепились к приемы 9, который является, в некотором смысле, "провокацией", оправдывающей "отвязное" название статьи. Я отчасти соглашусь с Вами и заменю знак "_" в теле строки на нечто более осмысленное, например "Край". Тогда, на мой взгляд строка
"Пока А< =Б Цикл М.Добавить(Новый Структура(Поля,А,Мин(Край(А),Б)));А=Край(А)+1 КонецЦикла"
будет вполне читаемой.
Любой рефакторинг увеличивает время разработки. Выигрыш получается потом.
Читабельность(забудьте на секунду про прием 9 - он исключение) я стараюсь не ухудшать.
Данная функция является готовым законченным решением. Она не требует внесения изменений внутри нее. Выходные и праздничные дни нужно исключать не "соединяя ужа с ежом" (такого бреда в 1С предостаточно), а постобработкой полученных на первом этапе периодов (подкинули отличную идею - обязательно покажу как это максимально просто сделать!), то есть еще важно правильно структурировать код.
Как раз для будущего развития мы и убираем постоянно мусор в коде, чтобы не спотыкаться о него впоследствии.
Мусор это то, что нельзя использовать повторно. Подробный код - это залог на будущую модернизацию кода.
Выигрыш в чем?? Замерьте время выполнения варианта 1 и варианта 9, там 0.1% прироста нет.
Т.е. вы призываете всех писать недокументируемый, недорабатываемый, неустойчивый к ошибкам код исключительно из личных предпочтений?
Рефакторинг провожу(и требую от подчиненных) только в случае:
1) недостаточной производительности выполняемого участка
2) отсутствие комментов в коде(при большой сложности решаемой задачи)
3) универсализация кода, который раньше был решением частной задачи, а теперь используется вторично.
4) необходимость влиять на результат без внесений изменений в код(из режима предприятия)
Пример рефакторинга(с увеличением производительности участка примерно в 12 раз)
Было
Скрытый текст |
|---|
| Процедура СтарыйКод()
// //Если Не ПустаяСтрока(СокрЛП(ДокСпец.ДокументОснование)) Тогда // Если НЕ ДокСпец.ДокументОснование.Пустая() Тогда // ТабличныйПроцессор.Range("J3").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СокрЛП(ДокСпец.ДокументОснование.Контрагент); // КонецЕсли; //КонецЕсли; //ТабличныйПроцессор.Range("J4").Select(); //ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "№ "+СокрЛП(Строка(ДокСпец.НомерЛистаЗамеров))+" от "+Лев(СокрЛП(ДокСпец.ДатаЛистаЗамеров),СтрДлина(СокрЛП(ДокСпец.ДатаЛистаЗамеров))-8); //ТабличныйПроцессор.Range("J5").Select(); //ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ДокСпец.Дата; //ТабличныйПроцессор.Range("J6").Select(); //Если СокрЛП(ДокСпец.ПредпологаемаяДатаОтгрузки) = "01.01.0001 0:00:00" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "не определен"; //Иначе // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ДокСпец.ПредпологаемаяДатаОтгрузки; //КонецЕсли; //ТабличныйПроцессор.Range("J8").Select(); //ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ЗначДвер; //ГлубинаСтеновогоПроема_Верх = ПолучитьЗначениеХарактеристики("ГлубинаСтеновогоПроема_Прав",Характеристика,СтрТек.Номенклатура); //ГлубинаСтеновогоПроема_Сред = ПолучитьЗначениеХарактеристики("ГлубинаСтеновогоПроема_Сред",Характеристика,СтрТек.Номенклатура); //ГлубинаСтеновогоПроема_Низ = ПолучитьЗначениеХарактеристики("ГлубинаСтеновогоПроема_Низ",Характеристика,СтрТек.Номенклатура); ////Диагональ_Лев = ПолучитьЗначениеХарактеристики("Диагональ_Лев",Характеристика,СтрТек.Номенклатура); ////Диагональ_Прав = ПолучитьЗначениеХарактеристики("Диагональ_Прав",Характеристика,СтрТек.Номенклатура); ////Уклон = ПолучитьЗначениеХарактеристики("Уклон",Характеристика,СтрТек.Номенклатура); //Параметры = ПолучитьЗначениеХарактеристики("Параметры",Характеристика,СтрТек.Номенклатура); //ОтгружатьВсборе = ПолучитьЗначениеХарактеристики("ОтгружатьВсборе",Характеристика,СтрТек.Номенклатура); //Если ОтгружатьВсборе = "" ТОгда // ОтгружатьВсборе = Ложь; //КонецЕсли; ////НеобходимостьЖесткойУпаковки = ПолучитьЗначениеХарактеристики("НеобходимостьЖесткойУпаковки",Характеристика,СтрТек.Номенклатура); ////ОкраскаRALClassic = ПолучитьЗначениеХарактеристики("ОкраскаRALClassic",Характеристика,СтрТек.Номенклатура); //Попытка // ГлубинаСтеновогоПроема_Верх = Число(ГлубинаСтеновогоПроема_Верх); //Исключение // ГлубинаСтеновогоПроема_Верх = 0; //КонецПопытки; //Попытка // ГлубинаСтеновогоПроема_Сред = Число(ГлубинаСтеновогоПроема_Сред); //Исключение // ГлубинаСтеновогоПроема_Сред = 0; //КонецПопытки; //Попытка // ГлубинаСтеновогоПроема_Низ = Число(ГлубинаСтеновогоПроема_Низ); //Исключение // ГлубинаСтеновогоПроема_Низ = 0; //КонецПопытки; //Глубина = Макс(ГлубинаСтеновогоПроема_Верх,ГлубинаСтеновогоПроема_Сред,ГлубинаСтеновогоПроема_Низ); //ТабличныйПроцессор.Range("J9").Select(); //ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ?(Глубина>0,СокрЛП(Строка(Глубина)),"0"); //ТабличныйПроцессор.Range("J10").Select(); //Если ОтгружатьВсборе Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "в сборе"; //Иначе // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "отдельно"; //КонецЕсли; //ТабличныйПроцессор.Range("J11").Select(); //ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; //Если ДокСпец.ДополнительныеОпции.Количество() > 0 Тогда // Для ы = 0 По (ДокСпец.ДополнительныеОпции.Количество()-1) Цикл // СтрДок = ДокСпец.ДополнительныеОпции[ы]; // If Нрег(СокрЛП(СтрДок.ВидДопОпции))="комплект креплений на подвесы" Then // Если СтрДок.Включена Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "да"; // Прервать; // EndIf; // КонецЕсли;; // EndDo; //EndIf; //Если (ВидДвери = "1_30") ИЛИ (ВидДвери = "1_60") Тогда // ТабличныйПроцессор.Range("J10").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "в сборе"; // ТабличныйПроцессор.Range("B23").Select(); // If Найти(ВРег(СокрЛП(СтрТек.Номенклатура.Наименование)),"Б")>0 Then // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // Иначе // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "да"; // КонецЕсли; // ТабличныйПроцессор.Range("C23").Select(); // If Найти(ВРег(СокрЛП(СтрТек.Номенклатура.Наименование)),"Л")>0 Then // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "левая"; // Иначе // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "правая"; // КонецЕсли; // ТабличныйПроцессор.Range("N23").Select(); // If Найти(ВРег(СокрЛП(СтрТек.Номенклатура.Наименование)),"Л")>0 Then // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "левый"; // Иначе // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "правый"; // КонецЕсли; // ТабличныйПроцессор.Range("Количество_дверей").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = КолДверей; // ВариантОтделки = нРег(СокрЛП(ПолучитьЗначениеХарактеристики("ПолеВыбораВариантаОтделки",Характеристика,СтрТек.Номенклатура))); // ЦветОтделки = нРег(СокрЛП(ПолучитьЗначениеХарактеристики("ПолеВыбораЦветОтделки",Характеристика,СтрТек.Номенклатура))); // //Если (Найти(ВариантОтделки,"пластик") <> 0) И (Найти(ЦветОтделки,"дуглас") <> 0) ТОгда // // ВариантОтделки = "лмдф"; // // ЦветОтделки = "венге"; // //КонецЕсли; // //-- // ТабличныйПроцессор.Range("Тип_покрытия").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ВариантОтделки; // ТабличныйПроцессор.Range("F23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ЦветОтделки; // ВысотаСтеновогоПроема_Лев = ПолучитьЗначениеХарактеристики("ВысотаСтеновогоПроема_Лев",Характеристика,СтрТек.Номенклатура); // ВысотаСтеновогоПроема_Сред = ПолучитьЗначениеХарактеристики("ВысотаСтеновогоПроема_Сред",Характеристика,СтрТек.Номенклатура); // ВысотаСтеновогоПроема_Прав = ПолучитьЗначениеХарактеристики("ВысотаСтеновогоПроема_Прав",Характеристика,СтрТек.Номенклатура); // Попытка // ВысотаСтеновогоПроема_Лев = Число(ВысотаСтеновогоПроема_Лев); // Исключение // ВысотаСтеновогоПроема_Лев = 0; // КонецПопытки; // Попытка // ВысотаСтеновогоПроема_Сред = Число(ВысотаСтеновогоПроема_Сред); // Исключение // ВысотаСтеновогоПроема_Сред = 0; // КонецПопытки; // Попытка // ВысотаСтеновогоПроема_Прав = Число(ВысотаСтеновогоПроема_Прав); // Исключение // ВысотаСтеновогоПроема_Прав = 0; // КонецПопытки; // ВысотаДвернойКоробки = 1; // //ВысотаДвернойКоробки = Мин(ВысотаСтеновогоПроема_Лев,ВысотаСтеновогоПроема_Сред,ВысотаСтеновогоПроема_Прав); // //ВысотаДвернойКоробки = ВысотаДвернойКоробки - ?(Параметры,10,0); // ТабличныйПроцессор.Range("Высота_дверного_блока").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ВысотаДвернойКоробки; // ШиринаСтеновогоПроема_Верх = ПолучитьЗначениеХарактеристики("ШиринаСтеновогоПроема_Верх",Характеристика,СтрТек.Номенклатура); // ШиринаСтеновогоПроема_Сред = ПолучитьЗначениеХарактеристики("ШиринаСтеновогоПроема_Сред",Характеристика,СтрТек.Номенклатура); // ШиринаСтеновогоПроема_Низ = ПолучитьЗначениеХарактеристики("ШиринаСтеновогоПроема_Низ",Характеристика,СтрТек.Номенклатура); // Попытка // ШиринаСтеновогоПроема_Верх = Число(ШиринаСтеновогоПроема_Верх); // Исключение // ШиринаСтеновогоПроема_Верх = 0; // КонецПопытки; // Попытка // ШиринаСтеновогоПроема_Сред = Число(ШиринаСтеновогоПроема_Сред); // Исключение // ШиринаСтеновогоПроема_Сред = 0; // КонецПопытки; // Попытка // ШиринаСтеновогоПроема_Низ = Число(ШиринаСтеновогоПроема_Низ); // Исключение // ШиринаСтеновогоПроема_Низ = 0; // КонецПопытки; // ШиринаДвернойКоробки = 1; // //ШиринаДвернойКоробки = Мин(ШиринаСтеновогоПроема_Верх,ШиринаСтеновогоПроема_Сред,ШиринаСтеновогоПроема_Низ); // //ШиринаДвернойКоробки = ШиринаДвернойКоробки - ?(Параметры,20,0); // ТабличныйПроцессор.Range("Ширина_дверного_блока").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ШиринаДвернойКоробки; // ШиринаДверногоПолотна = ШиринаДвернойКоробки-33-3-3-33+20; // ТабличныйПроцессор.Range("K23").Select(); // Фурнитура = ""; КодФурнитуры = ""; Доводчик = ""; Комплект = ""; ДоборнаяДоска = ""; // Порог = ""; Пена = ""; КоличествоПены = 0; Антипаника = ""; ХарактеристикаФурнитуры = ""; // ХарактеристикаКомплекта = ""; // Если ДокСпец.ДополнительныеОпции.Количество() > 0 Тогда // Для ы = 0 По (ДокСпец.ДополнительныеОпции.Количество()-1) Цикл // СтрДок = ДокСпец.ДополнительныеОпции[ы]; // If Нрег(СокрЛП(СтрДок.ВидДопОпции))="фурнитура" Then // Если СтрДок.Включена Тогда // Фурнитура = СтрДок.Номенклатура; // ХарактеристикаФурнитуры = СтрДок.ХарактеристикаНоменклатуры; // Если ПустаяСтрока(СокрЛП(Фурнитура)) ТОгда // Фурнитура = СтрДок.Марка; // КодФурнитуры = СтрДок.Код; // Иначе // Если Фурнитура.Пустая() Тогда // Фурнитура = СтрДок.Марка; // КодФурнитуры = СтрДок.Код; // КонецЕсли; // КонецЕсли; // EndIf; // ИначеЕсли Нрег(СокрЛП(СтрДок.ВидДопОпции))="доводчик дверной" Then // Если СтрДок.Включена Тогда // Доводчик = СтрДок.Номенклатура; // Если ПустаяСтрока(СокрЛП(Доводчик)) ТОгда // Доводчик = СтрДок.Марка; // Иначе // Если Доводчик.Пустая() Тогда // Доводчик = СтрДок.Марка; // КонецЕсли; // КонецЕсли; // EndIf; // ИначеЕсли Нрег(СокрЛП(СтрДок.ВидДопОпции))="комплект наличников" Then // Если СтрДок.Включена Тогда // Комплект = СтрДок.Номенклатура; // ХарактеристикаКомплекта = СтрДок.ХарактеристикаНоменклатуры; // Если ПустаяСтрока(СокрЛП(Комплект)) ТОгда // Комплект = СтрДок.Марка; // Иначе // Если Комплект.Пустая() Тогда // Комплект = СтрДок.Марка; // КонецЕсли; // КонецЕсли; // EndIf; // ИначеЕсли Нрег(СокрЛП(СтрДок.ВидДопОпции))="доборная доска" Then // Если СтрДок.Включена Тогда // ДоборнаяДоска = СтрДок.Номенклатура; // Если ПустаяСтрока(СокрЛП(ДоборнаяДоска)) ТОгда // ДоборнаяДоска = СтрДок.Марка; // Иначе // Если ДоборнаяДоска.Пустая() Тогда // ДоборнаяДоска = СтрДок.Марка; // КонецЕсли; // КонецЕсли; // EndIf; // ИначеЕсли Нрег(СокрЛП(СтрДок.ВидДопОпции))="автоматический порог" Then // Если СтрДок.Включена Тогда // Порог = СтрДок.Номенклатура; // Если ПустаяСтрока(СокрЛП(Порог)) ТОгда // Порог = СтрДок.Марка; // Иначе // Если Порог.Пустая() Тогда // Порог = СтрДок.Марка; // КонецЕсли; // КонецЕсли; // EndIf; // ИначеЕсли Нрег(СокрЛП(СтрДок.ВидДопОпции))="пена герметизирующая огнестойкая" Then // Если СтрДок.Включена Тогда // Пена = СтрДок.Номенклатура; // Если ПустаяСтрока(СокрЛП(Пена)) ТОгда // Пена = СтрДок.Марка; // Иначе // Если Пена.Пустая() Тогда // Пена = СтрДок.Марка; // КонецЕсли; // КонецЕсли; // КоличествоПены = Цел(СтрДок.Количество/КолДверей); // EndIf; // ИначеЕсли Нрег(СокрЛП(СтрДок.ВидДопОпции))="система ""антипаника""" Then // Если СтрДок.Включена Тогда // Антипаника = СтрДок.Номенклатура; // Если ПустаяСтрока(СокрЛП(Антипаника)) ТОгда // Антипаника = СтрДок.Марка; // Иначе // Если Антипаника.Пустая() Тогда // Антипаника = СтрДок.Марка; // КонецЕсли; // КонецЕсли; // EndIf; // КонецЕсли;; // EndDo; // EndIf; // ЦветОбщ = ""; // Если Не ПустаяСтрока(СокрЛП(ХарактеристикаФурнитуры)) Тогда // Если ТипЗнч(ХарактеристикаФурнитуры) <> Тип("Строка") ТОгда // ОтбНом = Новый Структура("Объект",ХарактеристикаФурнитуры); // РегВыбор = РегистрыСведений.ЗначенияСвойствОбъектов.Выбрать(ОтбНом); // Пока РегВыбор.Следующий() Цикл // Если (НРег(СокрЛП(РегВыбор.Свойство.Наименование))="цвет") Тогда // ЦветОбщ = нРег(СокрЛП(РегВыбор.Значение)); // КонецЕсли; // КонецЦикла; // КонецЕсли; // Если ПустаяСтрока(ЦветОбщ) Тогда // ЦветОбщ = "хром"; // КонецЕсли; // Иначе // ЦветОбщ = "хром"; // КонецЕсли; // Если ЦветОбщ = "золото" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "Д1"; // ИначеЕсли ЦветОбщ = "бронза" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "Д2"; // ИначеЕсли ЦветОбщ = "хром" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "Д3"; // Иначе // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ""; // КонецЕсли; // ТабличныйПроцессор.Range("L23").Select(); // ЗначЕкс = ТабличныйПроцессор.ActiveCell.Value; // Если ЦветОбщ = "хром" Тогда // н = Найти(ЗначЕкс,"никель"); // Если н=0 Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СтрЗаменить(ЗначЕкс,"латунь","никель"); // КонецЕсли; // Иначе // н = Найти(ЗначЕкс,"латунь"); // Если н=0 Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СтрЗаменить(ЗначЕкс,"никель","латунь"); // КонецЕсли; // КонецЕсли; // ТабличныйПроцессор.Range("P23").Select(); // If Найти(ВРег(СокрЛП(СтрТек.Номенклатура.Наименование)),"Л")>0 Then // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "Fe\Zn - L с бок рег"; // Иначе // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "Fe\Zn - R с бок рег"; // КонецЕсли; // ТабличныйПроцессор.Range("R23").Select(); // Если нРег(ЦветОтделки) = "ольха" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "бук"; // ИначеЕсли нРег(ЦветОтделки) = "бук" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "бук"; // ИначеЕсли нРег(ЦветОтделки) = "вишня" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "темно-коричневый"; // ИначеЕсли (нРег(ЦветОтделки) = "дуглас") ИЛИ (нРег(ЦветОтделки) = "венге") Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "темно-коричневый"; // ИначеЕсли нРег(ЦветОтделки) = "белый" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "белый"; // ИначеЕсли нРег(ЦветОтделки) = "дуб" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "бук"; // Иначе // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "бук"; // КонецЕсли; // ТабличныйПроцессор.Range("S23").Select(); // Если нРег(ЦветОтделки) = "ольха" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "бежевый"; // ИначеЕсли нРег(ЦветОтделки) = "бук" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "бежевый"; // ИначеЕсли нРег(ЦветОтделки) = "вишня" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "коричневый"; // ИначеЕсли (нРег(ЦветОтделки) = "дуглас") ИЛИ (нРег(ЦветОтделки) = "венге") Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "коричневый"; // ИначеЕсли нРег(ЦветОтделки) = "белый" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "бежевый"; // ИначеЕсли нРег(ЦветОтделки) = "дуб" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "бежевый"; // Иначе // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "бежевый"; // КонецЕсли; // ТабличныйПроцессор.Range("AB23").Select(); // Если НЕ ПустаяСтрока(СокрЛП(Доводчик)) Тогда // ЦветДоводчика = ""; // Если ТипЗнч(Доводчик) <> Тип("Строка") Тогда // ОтбНом = Новый Структура("Объект",Доводчик); // РегВыбор = РегистрыСведений.ЗначенияСвойствОбъектов.Выбрать(ОтбНом); // Пока РегВыбор.Следующий() Цикл // Если (НРег(СокрЛП(РегВыбор.Свойство.Наименование))="цвет доводчика") Тогда // ЦветДоводчика = нРег(СокрЛП(РегВыбор.Значение)); // КонецЕсли; // КонецЦикла; // КонецЕсли; // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СокрЛП(Доводчик)+" "+СокрЛП(ЦветДоводчика); // Иначе // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // ТабличныйПроцессор.Range("AB52").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = 0; // КонецЕсли; // Если Не ПустаяСтрока(СокрЛП(Комплект)) Тогда // ВариантУстановки = ""; ТипДверногоНаличника = ""; // Если Не ПустаяСтрока(СокрЛП(ХарактеристикаКомплекта)) Тогда // Если ТипЗнч(ХарактеристикаКомплекта) <> Тип("Строка") ТОгда // ОтбНом = Новый Структура("Объект",ХарактеристикаКомплекта); // РегВыбор = РегистрыСведений.ЗначенияСвойствОбъектов.Выбрать(ОтбНом); // Пока РегВыбор.Следующий() Цикл // Если (НРег(СокрЛП(РегВыбор.Свойство.Наименование))="вариант установки") Тогда // ВариантУстановки = нРег(СокрЛП(РегВыбор.Значение)); // КонецЕсли; // Если (НРег(СокрЛП(РегВыбор.Свойство.Наименование))="тип") Тогда // ТипДверногоНаличника = нРег(СокрЛП(РегВыбор.Значение)); // КонецЕсли; // КонецЦикла; // КонецЕсли; // КонецЕсли; // ТабличныйПроцессор.Range("AD23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ТипДверногоНаличника; // ТабличныйПроцессор.Range("AC23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ВариантУстановки; // Иначе // ТабличныйПроцессор.Range("AC23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // ТабличныйПроцессор.Range("AD23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // КонецЕсли; // Если Не ПустаяСтрока(СокрЛП(ДоборнаяДоска)) ТОгда // //ТабличныйПроцессор.Range("AE23").Select(); // //If ДокСпец.ВариантУстановкиДоборнойДоски = 1 Then // // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "с наружной стороны"; // //ElsIf ДокСпец.ВариантУстановкиДоборнойДоски = 2 Then // // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "с внутренней стороны"; // //ElsIf ДокСпец.ВариантУстановкиДоборнойДоски = 3 Then // // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "с двух сторон"; // //Иначе // // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // //EndIf; // Иначе // ТабличныйПроцессор.Range("AE23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // КонецЕсли; // Если НЕ ПустаяСтрока(СокрЛП(Порог)) ТОгда // ТабличныйПроцессор.Range("AF23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ПолучитьДлинуПорога(ШиринаДверногоПолотна);//(Цел(ШиринаДверногоПолотна/100)*100)+30; // Иначе // ТабличныйПроцессор.Range("AF23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // КонецЕсли; // Если НЕ ПустаяСтрока(СокрЛП(Пена)) ТОгда // ТабличныйПроцессор.Range("AI15").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СокрЛП(Пена); // ТабличныйПроцессор.Range("AI23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "да"; // ТабличныйПроцессор.Range("AI52").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = КоличествоПены; // Иначе // ТабличныйПроцессор.Range("AI23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // ТабличныйПроцессор.Range("AI52").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = 0; // EndIf; // Если НЕ ПустаяСтрока(СокрЛП(Антипаника)) Тогда // ТабличныйПроцессор.Range("AG23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СокрЛП(Антипаника); // ТабличныйПроцессор.Range("AH23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СокрЛП(Антипаника); // Иначе // ТабличныйПроцессор.Range("AG23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // ТабличныйПроцессор.Range("AH23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // КонецЕсли; // If ТипЗнч(Фурнитура) = Тип("Строка") Then // Если Не ПустаяСтрока(Фурнитура) ТОгда // ТабличныйПроцессор.Range("AJ23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СокрЛП(Фурнитура)+" "+СокрЛП(КодФурнитуры); // ТабличныйПроцессор.Range("AK23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СокрЛП(Фурнитура)+" "+СокрЛП(КодФурнитуры); // Иначе // ТабличныйПроцессор.Range("AJ23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // ТабличныйПроцессор.Range("AK23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // КонецЕсли; // Иначе // If НЕ Фурнитура.Пустая() Then // ТипФурнитуры = ""; // ОтбНом = Новый Структура("Объект",Фурнитура); // РегВыбор = РегистрыСведений.ЗначенияСвойствОбъектов.Выбрать(ОтбНом); // Пока РегВыбор.Следующий() Цикл // Если (НРег(СокрЛП(РегВыбор.Свойство.Наименование))="тип фурнитуры") Тогда // ТипФурнитуры = нРег(СокрЛП(РегВыбор.Значение)); // ТабличныйПроцессор.Range("AJ23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СокрЛП(Фурнитура)+" "+СокрЛП(ТипФурнитуры)+" "+СокрЛП(ЦветОбщ); // ТабличныйПроцессор.Range("AK23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СокрЛП(Фурнитура)+" "+СокрЛП(ТипФурнитуры)+" "+СокрЛП(ЦветОбщ); // Прервать; // КонецЕсли; // КонецЦикла; // Если ПустаяСтрока(ТипФурнитуры) ТОгда // ТабличныйПроцессор.Range("AJ23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СокрЛП(Фурнитура)+" "+СокрЛП(ЦветОбщ); // ТабличныйПроцессор.Range("AK23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СокрЛП(Фурнитура)+" "+СокрЛП(ЦветОбщ); // EndIf; // Иначе // ТабличныйПроцессор.Range("AJ23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // ТабличныйПроцессор.Range("AK23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // EndIf; // КонецЕсли; //Иначе // ТабличныйПроцессор.Range("A15").Select(); // РавнопольнаяД = ПолучитьЗначениеХарактеристики("ТипДвери_Равнопольная",Характеристика,СтрТек.Номенклатура); // Если ПустаяСтрока(РавнопольнаяД) ТОгда // Равнопольная = Ложь; // ИначеЕсли РавнопольнаяД=Undefined Тогда // Равнопольная = Ложь; // Иначе // Равнопольная = РавнопольнаяД; // КонецЕсли; // Если Равнопольная ТОгда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "двупольная равнопольная"; // Иначе // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "двупольная неравнопольная"; // КонецЕсли; // ТабличныйПроцессор.Range("Наличие_порога").Select(); // If Найти(ВРег(СокрЛП(СтрТек.Номенклатура.Наименование)),"Б")>0 Then // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // Иначе // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "да"; // КонецЕсли; // ТабличныйПроцессор.Range("C23").Select(); // If Найти(ВРег(СокрЛП(СтрТек.Номенклатура.Наименование)),"Л")>0 Then // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "левая"; // Иначе // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "правая"; // КонецЕсли; // ТабличныйПроцессор.Range("P23").Select(); // If Найти(ВРег(СокрЛП(СтрТек.Номенклатура.Наименование)),"Л")>0 Then // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "левый"; // Иначе // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "правый"; // КонецЕсли; // ТабличныйПроцессор.Range("Количество_дверей").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = КолДверей; // ВариантОтделки = нРег(СокрЛП(ПолучитьЗначениеХарактеристики("ПолеВыбораВариантаОтделки",Характеристика,СтрТек.Номенклатура))); // ЦветОтделки = нРег(СокрЛП(ПолучитьЗначениеХарактеристики("ПолеВыбораЦветОтделки",Характеристика,СтрТек.Номенклатура))); // //Если (Найти(ВариантОтделки,"пластик") <> 0) И (Найти(ЦветОтделки,"дуглас") <> 0) ТОгда // // ВариантОтделки = "лмдф"; // // ЦветОтделки = "венге"; // //КонецЕсли; // //-- // ТабличныйПроцессор.Range("Тип_покрытия").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ВариантОтделки; // ТабличныйПроцессор.Range("Цвет_покрытия").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ЦветОтделки; // ВысотаСтеновогоПроема_Лев = ПолучитьЗначениеХарактеристики("ВысотаСтеновогоПроема_Лев",Характеристика,СтрТек.Номенклатура); // ВысотаСтеновогоПроема_Сред = ПолучитьЗначениеХарактеристики("ВысотаСтеновогоПроема_Сред",Характеристика,СтрТек.Номенклатура); // ВысотаСтеновогоПроема_Прав = ПолучитьЗначениеХарактеристики("ВысотаСтеновогоПроема_Прав",Характеристика,СтрТек.Номенклатура); // Попытка // ВысотаСтеновогоПроема_Лев = Число(ВысотаСтеновогоПроема_Лев); // Исключение // ВысотаСтеновогоПроема_Лев = 0; // КонецПопытки; // Попытка // ВысотаСтеновогоПроема_Сред = Число(ВысотаСтеновогоПроема_Сред); // Исключение // ВысотаСтеновогоПроема_Сред = 0; // КонецПопытки; // Попытка // ВысотаСтеновогоПроема_Прав = Число(ВысотаСтеновогоПроема_Прав); // Исключение // ВысотаСтеновогоПроема_Прав = 0; // КонецПопытки; // ВысотаДвернойКоробки = Мин(ВысотаСтеновогоПроема_Лев,ВысотаСтеновогоПроема_Сред,ВысотаСтеновогоПроема_Прав); // ВысотаДвернойКоробки = ВысотаДвернойКоробки - ?(Параметры,10,0); // ТабличныйПроцессор.Range("Высота_дверного_блока").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ВысотаДвернойКоробки; // ШиринаСтеновогоПроема_Верх = ПолучитьЗначениеХарактеристики("ШиринаСтеновогоПроема_Верх",Характеристика,СтрТек.Номенклатура); // ШиринаСтеновогоПроема_Сред = ПолучитьЗначениеХарактеристики("ШиринаСтеновогоПроема_Сред",Характеристика,СтрТек.Номенклатура); // ШиринаСтеновогоПроема_Низ = ПолучитьЗначениеХарактеристики("ШиринаСтеновогоПроема_Низ",Характеристика,СтрТек.Номенклатура); // Попытка // ШиринаСтеновогоПроема_Верх = Число(ШиринаСтеновогоПроема_Верх); // Исключение // ШиринаСтеновогоПроема_Верх = 0; // КонецПопытки; // Попытка // ШиринаСтеновогоПроема_Сред = Число(ШиринаСтеновогоПроема_Сред); // Исключение // ШиринаСтеновогоПроема_Сред = 0; // КонецПопытки; // Попытка // ШиринаСтеновогоПроема_Низ = Число(ШиринаСтеновогоПроема_Низ); // Исключение // ШиринаСтеновогоПроема_Низ = 0; // КонецПопытки; // ШиринаДвернойКоробки = Мин(ШиринаСтеновогоПроема_Верх,ШиринаСтеновогоПроема_Сред,ШиринаСтеновогоПроема_Низ); // ШиринаДвернойКоробки = ШиринаДвернойКоробки - ?(Параметры,20,0); // ТабличныйПроцессор.Range("Ширина_дверного_блока").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ШиринаДвернойКоробки; // ШиринаАктивнойСтворки = ПолучитьЗначениеХарактеристики("ШиринаАктивногоПолотна",Характеристика,СтрТек.Номенклатура); // ТабличныйПроцессор.Range("Ширина_активного_полотна").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ШиринаАктивнойСтворки; // ШиринаДверногоПолотнаАктивн = ШиринаАктивнойСтворки; // ШиринаДверногоПолотна = ШиринаДвернойКоробки-33-33-3-3-2+10-ШиринаАктивнойСтворки+20; // Фурнитура = ""; КодФурнитуры = ""; Доводчик = ""; Комплект = ""; ДоборнаяДоска = ""; // Порог = ""; Пена = ""; КоличествоПены = 0; Антипаника = ""; ХарактеристикаФурнитуры = ""; // ХарактеристикаКомплекта = ""; // Если ДокСпец.ДополнительныеОпции.Количество() > 0 Тогда // Для ы = 0 По (ДокСпец.ДополнительныеОпции.Количество()-1) Цикл // СтрДок = ДокСпец.ДополнительныеОпции[ы]; // If Нрег(СокрЛП(СтрДок.ВидДопОпции))="фурнитура" Then // Если СтрДок.Включена Тогда // Фурнитура = СтрДок.Номенклатура; // ХарактеристикаФурнитуры = СтрДок.ХарактеристикаНоменклатуры; // Если ПустаяСтрока(СокрЛП(Фурнитура)) ТОгда // Фурнитура = СтрДок.Марка; // КодФурнитуры = СтрДок.Код; // Иначе // Если Фурнитура.Пустая() Тогда // Фурнитура = СтрДок.Марка; // КодФурнитуры = СтрДок.Код; // КонецЕсли; // КонецЕсли; // EndIf; // ИначеЕсли Нрег(СокрЛП(СтрДок.ВидДопОпции))="доводчик дверной" Then // Если СтрДок.Включена Тогда // Доводчик = СтрДок.Номенклатура; // Если ПустаяСтрока(СокрЛП(Доводчик)) ТОгда // Доводчик = СтрДок.Марка; // Иначе // Если Доводчик.Пустая() Тогда // Доводчик = СтрДок.Марка; // КонецЕсли; // КонецЕсли; // EndIf; // ИначеЕсли Нрег(СокрЛП(СтрДок.ВидДопОпции))="комплект наличников" Then // Если СтрДок.Включена Тогда // Комплект = СтрДок.Номенклатура; // ХарактеристикаКомплекта = СтрДок.ХарактеристикаНоменклатуры; // Если ПустаяСтрока(СокрЛП(Комплект)) ТОгда // Комплект = СтрДок.Марка; // Иначе // Если Комплект.Пустая() Тогда // Комплект = СтрДок.Марка; // КонецЕсли; // КонецЕсли; // EndIf; // ИначеЕсли Нрег(СокрЛП(СтрДок.ВидДопОпции))="доборная доска" Then // Если СтрДок.Включена Тогда // ДоборнаяДоска = СтрДок.Номенклатура; // Если ПустаяСтрока(СокрЛП(ДоборнаяДоска)) ТОгда // ДоборнаяДоска = СтрДок.Марка; // Иначе // Если ДоборнаяДоска.Пустая() Тогда // ДоборнаяДоска = СтрДок.Марка; // КонецЕсли; // КонецЕсли; // EndIf; // ИначеЕсли Нрег(СокрЛП(СтрДок.ВидДопОпции))="автоматический порог" Then // Если СтрДок.Включена Тогда // Порог = СтрДок.Номенклатура; // Если ПустаяСтрока(СокрЛП(Порог)) ТОгда // Порог = СтрДок.Марка; // Иначе // Если Порог.Пустая() Тогда // Порог = СтрДок.Марка; // КонецЕсли; // КонецЕсли; // EndIf; // ИначеЕсли Нрег(СокрЛП(СтрДок.ВидДопОпции))="пена герметизирующая огнестойкая" Then // Если СтрДок.Включена Тогда // Пена = СтрДок.Номенклатура; // Если ПустаяСтрока(СокрЛП(Пена)) ТОгда // Пена = СтрДок.Марка; // Иначе // Если Пена.Пустая() Тогда // Пена = СтрДок.Марка; // КонецЕсли; // КонецЕсли; // КоличествоПены = Цел(СтрДок.Количество/КолДверей); // EndIf; // ИначеЕсли Нрег(СокрЛП(СтрДок.ВидДопОпции))="система ""антипаника""" Then // Если СтрДок.Включена Тогда // Антипаника = СтрДок.Номенклатура; // Если ПустаяСтрока(СокрЛП(Антипаника)) ТОгда // Антипаника = СтрДок.Марка; // Иначе // Если Антипаника.Пустая() Тогда // Антипаника = СтрДок.Марка; // КонецЕсли; // КонецЕсли; // EndIf; // КонецЕсли;; // EndDo; // EndIf; // ЦветОбщ = ""; // Если Не ПустаяСтрока(СокрЛП(ХарактеристикаФурнитуры)) Тогда // Если ТипЗнч(ХарактеристикаФурнитуры) <> Тип("Строка") ТОгда // ОтбНом = Новый Структура("Объект",ХарактеристикаФурнитуры); // РегВыбор = РегистрыСведений.ЗначенияСвойствОбъектов.Выбрать(ОтбНом); // Пока РегВыбор.Следующий() Цикл // Если (НРег(СокрЛП(РегВыбор.Свойство.Наименование))="цвет") Тогда // ЦветОбщ = нРег(СокрЛП(РегВыбор.Значение)); // КонецЕсли; // КонецЦикла; // КонецЕсли; // Если ПустаяСтрока(ЦветОбщ) Тогда // ЦветОбщ = "хром"; // КонецЕсли; // Иначе // ЦветОбщ = "хром"; // КонецЕсли; // ТабличныйПроцессор.Range("M23").Select(); // Если ЦветОбщ = "золото" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "Д1"; // ИначеЕсли ЦветОбщ = "бронза" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "Д2"; // ИначеЕсли ЦветОбщ = "хром" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "Д3"; // Иначе // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ""; // КонецЕсли; // ТабличныйПроцессор.Range("N23").Select(); // ЗначЕкс = ТабличныйПроцессор.ActiveCell.Value; // Если ЦветОбщ = "хром" Тогда // н = Найти(ЗначЕкс,"никель"); // Если н=0 Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СтрЗаменить(ЗначЕкс,"латунь","никель"); // КонецЕсли; // Иначе // н = Найти(ЗначЕкс,"латунь"); // Если н=0 Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СтрЗаменить(ЗначЕкс,"никель","латунь"); // КонецЕсли; // КонецЕсли; // ТабличныйПроцессор.Range("R23").Select(); // If Найти(ВРег(СокрЛП(СтрТек.Номенклатура.Наименование)),"Л")>0 Then // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "Fe\Zn - L с бок рег"; // Иначе // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "Fe\Zn - R с бок рег"; // КонецЕсли; // ТабличныйПроцессор.Range("S23").Select(); // If Найти(ВРег(СокрЛП(СтрТек.Номенклатура.Наименование)),"Л")>0 Then // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "Fe\Zn - R с бок рег"; // Иначе // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "Fe\Zn - L с бок рег"; // КонецЕсли; // ТабличныйПроцессор.Range("U23").Select(); // Если нРег(ЦветОтделки) = "ольха" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "бук"; // ИначеЕсли нРег(ЦветОтделки) = "бук" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "бук"; // ИначеЕсли нРег(ЦветОтделки) = "вишня" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "темно-коричневый"; // ИначеЕсли (нРег(ЦветОтделки) = "дуглас") ИЛИ (нРег(ЦветОтделки) = "венге") Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "темно-коричневый"; // ИначеЕсли нРег(ЦветОтделки) = "белый" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "белый"; // ИначеЕсли нРег(ЦветОтделки) = "дуб" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "бук"; // Иначе // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "бук"; // КонецЕсли; // ТабличныйПроцессор.Range("V23").Select(); // Если нРег(ЦветОтделки) = "ольха" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "бежевый"; // ИначеЕсли нРег(ЦветОтделки) = "бук" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "бежевый"; // ИначеЕсли нРег(ЦветОтделки) = "вишня" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "коричневый"; // ИначеЕсли (нРег(ЦветОтделки) = "дуглас") ИЛИ (нРег(ЦветОтделки) = "венге") Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "коричневый"; // ИначеЕсли нРег(ЦветОтделки) = "белый" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "бежевый"; // ИначеЕсли нРег(ЦветОтделки) = "дуб" Тогда // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "бежевый"; // Иначе // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "бежевый"; // КонецЕсли; // ТабличныйПроцессор.Range("AF23").Select(); // Если Не ПустаяСтрока(СокрЛП(Доводчик)) Тогда // ЦветДоводчика = ""; // Если ТипЗнч(Доводчик) <> Тип("Строка") Тогда // ОтбНом = Новый Структура("Объект",Доводчик); // РегВыбор = РегистрыСведений.ЗначенияСвойствОбъектов.Выбрать(ОтбНом); // Пока РегВыбор.Следующий() Цикл // Если (НРег(СокрЛП(РегВыбор.Свойство.Наименование))="цвет доводчика") Тогда // ЦветДоводчика = нРег(СокрЛП(РегВыбор.Значение)); // КонецЕсли; // КонецЦикла; // КонецЕсли; // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СокрЛП(Доводчик)+" "+СокрЛП(ЦветДоводчика); // Иначе // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // ТабличныйПроцессор.Range("AF52").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = 0; // КонецЕсли; // Если Не ПустаяСтрока(СокрЛП(Комплект)) Тогда // ВариантУстановки = ""; ТипДверногоНаличника = ""; // Если Не ПустаяСтрока(СокрЛП(ХарактеристикаКомплекта)) Тогда // Если ТипЗнч(ХарактеристикаКомплекта) <> Тип("Строка") ТОгда // ОтбНом = Новый Структура("Объект",ХарактеристикаКомплекта); // РегВыбор = РегистрыСведений.ЗначенияСвойствОбъектов.Выбрать(ОтбНом); // Пока РегВыбор.Следующий() Цикл // Если (НРег(СокрЛП(РегВыбор.Свойство.Наименование))="вариант установки") Тогда // ВариантУстановки = нРег(СокрЛП(РегВыбор.Значение)); // КонецЕсли; // Если (НРег(СокрЛП(РегВыбор.Свойство.Наименование))="тип") Тогда // ТипДверногоНаличника = нРег(СокрЛП(РегВыбор.Значение)); // КонецЕсли; // КонецЦикла; // КонецЕсли; // КонецЕсли; // ТабличныйПроцессор.Range("Вид_наличника").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ТипДверногоНаличника; // ТабличныйПроцессор.Range("Расположение_наличника").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ВариантУстановки; // Иначе // ТабличныйПроцессор.Range("Расположение_наличника").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // ТабличныйПроцессор.Range("Вид_наличника").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // КонецЕсли; // Если Не ПустаяСтрока(СокрЛП(ДоборнаяДоска)) Тогда // //ТабличныйПроцессор.Range("Доборная_доска").Select(); // //If ДокСпец.ВариантУстановкиДоборнойДоски = 1 Then // // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "с наружной стороны"; // //ElsIf ДокСпец.ВариантУстановкиДоборнойДоски = 2 Then // // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "с внутренней стороны"; // //ElsIf ДокСпец.ВариантУстановкиДоборнойДоски = 3 Then // // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "с двух сторон"; // //Иначе // // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // //EndIf; // Иначе // ТабличныйПроцессор.Range("Доборная_доска").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // КонецЕсли; // Если Не ПустаяСтрока(СокрЛП(Порог)) Тогда // ТабличныйПроцессор.Range("AJ23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ПолучитьДлинуПорога(ШиринаДверногоПолотнаАктивн);//(Цел(ШиринаДверногоПолотнаАктивн/100)*100)+30; // ТабличныйПроцессор.Range("AK23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = ПолучитьДлинуПорога(ШиринаДверногоПолотна);//(Цел(ШиринаДверногоПолотна/100)*100)+30; // Иначе // ТабличныйПроцессор.Range("AJ23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // ТабличныйПроцессор.Range("AK23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // КонецЕсли; // Если Не ПустаяСтрока(СокрЛП(Пена)) Тогда // ТабличныйПроцессор.Range("AN23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "да"; // ТабличныйПроцессор.Range("AN52").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = КоличествоПены; // Иначе // ТабличныйПроцессор.Range("AN23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // ТабличныйПроцессор.Range("AN52").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = 0; // КонецЕсли; // Если НЕ ПустаяСтрока(СокрЛП(Антипаника)) Тогда // ТабличныйПроцессор.Range("AL23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СокрЛП(Антипаника); // ТабличныйПроцессор.Range("AM23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СокрЛП(Антипаника); // Иначе // ТабличныйПроцессор.Range("AL23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // ТабличныйПроцессор.Range("AM23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // КонецЕсли; // If ТипЗнч(Фурнитура) = Тип("Строка") Then // ТабличныйПроцессор.Range("AO23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СокрЛП(Фурнитура)+" "+СокрЛП(КодФурнитуры); // ТабличныйПроцессор.Range("AP23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СокрЛП(Фурнитура)+" "+СокрЛП(КодФурнитуры); // Иначе // If НЕ Фурнитура.Пустая() Then // ТипФурнитуры = ""; // ОтбНом = Новый Структура("Объект",Фурнитура); // РегВыбор = РегистрыСведений.ЗначенияСвойствОбъектов.Выбрать(ОтбНом); // Пока РегВыбор.Следующий() Цикл // Если (НРег(СокрЛП(РегВыбор.Свойство.Наименование))="тип фурнитуры") Тогда // ТипФурнитуры = нРег(СокрЛП(РегВыбор.Значение)); // ТабличныйПроцессор.Range("AO23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СокрЛП(Фурнитура)+" "+СокрЛП(ТипФурнитуры)+" "+СокрЛП(ЦветОбщ); // ТабличныйПроцессор.Range("AP23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СокрЛП(Фурнитура)+" "+СокрЛП(ТипФурнитуры)+" "+СокрЛП(ЦветОбщ); // Break; // EndIf; // EndDo; // Если ПустаяСтрока(ТипФурнитуры) ТОгда // ТабличныйПроцессор.Range("AO23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СокрЛП(Фурнитура)+" "+СокрЛП(ЦветОбщ); // ТабличныйПроцессор.Range("AP23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СокрЛП(Фурнитура)+" "+СокрЛП(ЦветОбщ); // EndIf; // Иначе // ТабличныйПроцессор.Range("AO23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // ТабличныйПроцессор.Range("AP23").Select(); // ТабличныйПроцессор.ActiveCell.FormulaR1C1 = "нет"; // EndIf; // КонецЕсли; //КонецЕсли; КонецПроцедуры |
Стало
Скрытый текст |
|---|
| ТаблицаСвойств = Новый ТаблицаЗначений;
ТаблицаСвойств.Колонки.Добавить("ИмяРек",Новый ОписаниеТипов("Строка")); МассивТипов = Новый Массив; МассивТипов.Добавить(Тип("СправочникСсылка.Номенклатура")); МассивТипов.Добавить(Тип("СправочникСсылка.ХарактеристикиНоменклатуры")); ТаблицаСвойств.Колонки.Добавить("ЗначениеРек",Новый ОписаниеТипов(МассивТипов)); ТаблицаПрочихСвойств = Новый ТаблицаЗначений; МассивТипов = Новый Массив; МассивТипов.Добавить(Тип("Булево")); МассивТипов.Добавить(Тип("Строка")); ТаблицаПрочихСвойств.Колонки.Добавить("ИмяРек",Новый ОписаниеТипов("Строка")); ТаблицаПрочихСвойств.Колонки.Добавить("ЗначениеРек",Новый ОписаниеТипов(МассивТипов)); Для Каждого Рек из ДокСпец.Метаданные().Реквизиты Цикл Если ЗначениеЗаполнено(ДокСпец[Рек.Имя]) Тогда Если ТипЗнч(ДокСпец[Рек.Имя]) = Тип("СправочникСсылка.Номенклатура") или ТипЗнч(ДокСпец[Рек.Имя]) = Тип("СправочникСсылка.ХарактеристикиНоменклатуры") Тогда НовСтр = ТаблицаСвойств.Добавить(); НовСтр.ИмяРек = Рек.Имя; НовСтр.ЗначениеРек = ДокСпец[Рек.Имя]; Иначе НовСтр = ТаблицаПрочихСвойств.Добавить(); НовСтр.ИмяРек = Рек.Имя; НовСтр.ЗначениеРек = ДокСпец[Рек.Имя]; КонецЕсли; КонецЕсли; КонецЦикла; //обход тч доп.опции ТаблицаДопСвойств = ДокСпец.ДополнительныеОпции.Выгрузить(); Запрос=Новый Запрос; Запрос.Текст= "ВЫБРАТЬ | ТаблицаСвойств.ИмяРек, | ТаблицаСвойств.ЗначениеРек |ПОМЕСТИТЬ ТаблицаСвойств1 |ИЗ | &ТаблицаСвойств КАК ТаблицаСвойств"; Запрос.УстановитьПараметр("ТаблицаСвойств",ТаблицаСвойств); Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц; Запрос.Выполнить(); Запрос.Текст = "ВЫБРАТЬ | ЗначенияСвойствОбъектов.Объект, | ЗначенияСвойствОбъектов.Свойство, | ЗначенияСвойствОбъектов.Значение КАК ЗначениеРек, | ТаблицаСвойств1.ИмяРек |ИЗ | РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов | ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТаблицаСвойств1 КАК ТаблицаСвойств1 | ПО ЗначенияСвойствОбъектов.Объект = ТаблицаСвойств1.ЗначениеРек"; ТаблицаЗначенийСвойств = Запрос.Выполнить().Выгрузить(); ТабличныйПроцессор.Sheets("наряд-заказ для бригадира").Select(); ТаблицаАдресов = ПолучитьСрезАдресовЯчеек(СтрТек.ЛистЗамеров); //Запишем номера дверей Попытка ТабличныйПроцессор.Range("Номера_Дверей").Select(); ТабличныйПроцессор.ActiveCell.FormulaR1C1 = СокрЛП(ЗначДвер); Исключение Сообщить("Не найдена ячейка с номерами дверей."); КонецПопытки; Для Каждого Стр из ТаблицаАдресов Цикл Если ЗначениеЗаполнено(Стр.ЗначениеСвойства) Тогда Отбор = Новый Структура; Отбор.Вставить("ВидДопОпции",Стр.ЗначениеСвойства); Строки = ТаблицаДопСвойств.НайтиСтроки(Отбор); Если Строки.Количество() = 1 Тогда Попытка ТабличныйПроцессор.Range(Стр.АдресЯчейки).Select(); Исключение СтрокаОшибки = ("Ячейка "+Стр.АдресЯчейки+" не найдена"); КонецПопытки; Если СтрокаОшибки = "" Тогда ТабличныйПроцессор.ActiveCell.FormulaR1C1 = стрЗаменить(Строка(Строки[0][Стр.ИмяРеквизита]),Символы.НПП,""); КонецЕсли; КонецЕсли; ИначеЕсли ЗначениеЗаполнено(ДокСпец[Стр.ИмяРеквизита]) Тогда Отбор = Новый Структура; Отбор.Вставить("ИмяРек",Стр.ИмяРеквизита); Если ЗначениеЗаполнено(Стр.Свойство) Тогда Отбор.Вставить("Свойство",Стр.Свойство); Строки = ТаблицаЗначенийСвойств.НайтиСтроки(Отбор); Иначе Отбор.Вставить("ИмяРек",Стр.ИмяРеквизита); Строки = ТаблицаПрочихСвойств.НайтиСтроки(Отбор); КонецЕсли; Если Строки.Количество() = 1 Тогда СтрокаОшибки = ""; Попытка ТабличныйПроцессор.Range(Стр.АдресЯчейки).Select(); Исключение СтрокаОшибки = ("Ячейка "+Стр.АдресЯчейки+" не найдена"); КонецПопытки; Если СтрокаОшибки = "" Тогда ТабличныйПроцессор.ActiveCell.FormulaR1C1 = стрЗаменить(Строка(Строки[0].ЗначениеРек),Символы.НПП,""); КонецЕсли; ИначеЕсли Строки.Количество() > 1 Тогда Сообщить("Обнаружены дубли записей в регистре Адреса ячеек. Для корректной работы их необходимо удалить."); Возврат; КонецЕсли; КонецЕсли; КонецЦикла; |
В итоге - базовый функционал не изменен, скорость работы и возможность доработки повышены на порядок. Код отвязан от предопределенных значений и устойчив к любым ошибкам пользователя. В качестве приятного бонуса появилась возможность редактировать формулы в режиме предприятия.
Код, устойчивый к ошибкам - это и есть мой код. Чем меньше код, тем меньше вероятность ошибки (могу доказать математически). Где легче найти ошибку: в 254 знаках или в 500? Кстати, поверьте, такой код практически не приходится отлаживать (вариант 5-7), поскольку в него сразу встроены необходимые проверки.
Посмотрел Ваш код. Выводы: "... и эти люди запрещают мне ковырять в носу!".
Для читабельности не хватает отступов.
Обязательно выделите в отдельные функции или процедуры часто используемые фрагменты кода. Сможете их использовать повторно (сэкономите деньги заказчика или свою прибыль повысите), а размер основной функции должен укладываться в страницу.
Видно, что заботы о красоте кода здесь пока нет, а жаль, тут есть где развернуться.
Для примера посмотрите код УТ11 - он достаточно красив, на него можно равняться.
Код не имеющий ни одной проверки(лишние строчки же) даже на элементарную заполненость параметров, это НЕ устойчивый код.
Пример: в код, указанный в статье как эталонный, передаю 2 параметра, ДатаС не заполнена, ДатаПо 09.09.2013, итог - имею массив из 24152 периодов. А если я по этим периодам зарплату считаю? На каждый, например, для 200 сотрудников. Насколько залипнет 1С?. И это
?
при поиске ошибок легче там, где переменные человечески именованы, количество вложенности вызываемых процедур/функций не превышает двух, а логика расписана в комментах, т.е. все то, от чего вы нас призываете отказаться.
что там выносить в отдельную процедуру? объявления массивов, типов, цикл, запрос, добавление строки? как это позволит "сэкономить" чьи бы то ни было деньги?
Так может сказать только тот, кто не дорабатывал УТ11. Отладка миллиона вложенных однострочных функций и тупиковых "Оповестить()" может пошатнуть даже самую стойкую психику. Для примера, при простом перепроведении заказа вызываются функции 24(!!!!) общих модулей.
Приведу в пример лютый трешак, который бродит по интернету
Функция ПадежС(z1,Знач z2=2,Знач z3="*",z4=0) Экспорт
z5=Найти(z1,"-");z6=?(z5=0,"","-"+ПадежС(Сред(z1,z5+1,СтрДлина(z1)-z5+1),z2,z3,z4));z1=?(z5=0,z1,Лев(z1,z5-1))//под составные слова
z1=НРег(?((z2<0)и(z4>1)и(z1<>""),Лев(z1,1)+".",z1));
z7=Прав(z1,3);z8=Прав(z7,2);z9=Прав(z8,1);
z2=?(((z4=2)и((z3="а")или(z3="ы"))и(Найти("бвгджзклмнопрстфхцчшщъиеу",z9)>0))или((z4=2)и(z3="ч")и(Найти("оиеу",z9)>0))или((z4=1)и(Найти("мия мяэ лия кия жая лея",z7)>0)),1,Макс(z2,-z2));
z5=СтрДлина(z1);
z10=Найти("ая ия ел ок яц ий па да ца ша ба та га ка",z8);
z11=?(z4=1,?(Найти("оеиую",z9)+Найти("их ых аа еа ёа иа оа уа ыа эа юа яа",z8)>0,-1,?((z3="а")или(z3="ы"),?(z10=1,8,?(z9="а",?(z10>18,3,9),-1)),?(((Найти("ой ый",z8)>0)и(z5>4))или(Найти("гий жий кий ний чий хий ший щий",z7)>0),10,0))),0);
z11=?(z11=0,?(z10=4,7,Найти(".чайяь",z9)), z11);
z12=Найти("лец вей дец пец мец нец рец вец аец иец ыец бер бей",z7);
z14=?((z11=10)и(z2<>5),?(Найти("чшщ",Лев(z7,1))+Найти("жий ний",z7)>0,"е","о"),?(z1="лев","ьв",?((Найти("аеёийоуэюя",Сред(z1,z5-3 ,1))+Найти("аеёийоуэюя",Лев(z7,1))=0)и(z12<>41),"",?(z10=7,"л",?(z10=10,"к",?(z10=13,"йц",?(z12=0,"",?((z12<9)или(z12=49),"ь"+?(z12=1,"ц",""),?(z12<33,"ц",?(z12<45,"йц","р"))))))))));
z14=?((z2=1)или(z11<0)или((z4=3)и(z3="ы")или(""=z1)),z1,Лев(z1,z5-?((z11=8)или(z14<>"")или(z11=10),2,?(z11>2,1,0)))+z14+СокрП(Сред("а у а "+Сред("оыыыоео",Найти(" внтчц",z9)+1,1)+"ме а у а еме "+?(Найти("гжкхш",Лев(z8,1))>0,"и","ы")+" е у ойе я ю я ем"+?(z10=16,"и","е")+" и е ю ейе и и ь ьюи и и ю ейи ойойуюойойойойу ойойгомуго"+?((z14="е")или(z10=16)или(Найти("гой хой кой",z7)>0),"и","ы")+"мм",10*?((z11=6)и(z3="ч"),4,z11)+2*z2-3,2)));
Возврат ?(z4>0,ВРег(Лев(z14,1))+Сред(z14,2),z14)+z6;
КонецФункции ПоказатьСовершенно не читаемый говнокод, зато автор хорошо так сэкономил на строках и символах. "Никакой избыточности" и нулевая гибкость.
В статье
Получается, что не все пишушие код люди могут себя называть "программистами".
Впрочем, ремесленников всегда будет больше, как и кода в стиле "что вижу, о том пою". Я, со своей стороны, понимаю этих людей, в идеале хотелось, чтобы они меня понимали тоже. Но получается, что люди, которым не нравится опера, просто затыкают уши.
копать карьер серебрянной ложечкой и во фраке, артистично оттопырив мизинчик, наверно очень эстетично, но в бизнесе обычно используют экскаватор, управляемый мужиками в промасленной спецовке.
Автор, Вы не перфекционист, а обфускацианист. Сам себе обфускатор:)
Автор пишет код для себя и только для себя выступая в роли компилятора для 1С с лозунгом "после меня - хоть трава не расти". Для ассемблера подобный подход оправдан и то не всегда.
Автор, даешь перенос всего кода во внешние DLL. А здесь можно публиковать ассемблерный или бинарный код этих DLL. Мы ведь все Нео и видим блондинок в розовом в строчках кода
Выполнить(СтрЗаменить("Пока А< =Б Цикл М.Добавить(Новый Структура(Поля,А,Мин(Край(А),Б)));А=Край(А)+1 КонецЦикла", "Край", "Конец" + Чего));согласен во многом с mymyka. Вы таки немного вредитель) ибо молодые юные программисты, которые пришли в 1с ибо не нашли себя на почве ассемблера и пошли в 1с пишут такой код, который потом фиг отладишь. Вам все таки стоит в статье больше внимания уделить пояснению что пункт 9 должен таки использоваться в том случае, когда процедура НИКОГДА не потребует изменения. Сам был увлекся рефакторингом кода пока не понял что все таки должна быть разумная средина) Одно дело сократить процедуру в 14000 строчек кода выбросив ненужные ответвления и сократив его до 3000 строк, другое дело втиснуть оставшиеся 3000 строчек в 10 но настолько непонятных, что доработка будет занимать больше времени чем поддержка 14000
а) работать быстрее
б) понятнее для коллег
Функция РазбитьПериод(ДатаНачало, ДатаКонец)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РАЗНОСТЬДАТ(&ДатаНачало, &ДатаКонец, МЕСЯЦ) КАК РазностьДат";
Запрос.УстановитьПараметр("ДатаНачало",ДатаНачало);
Запрос.УстановитьПараметр("ДатаКонец",ДатаКонец);
РазностьДат = Запрос.Выполнить().Выгрузить()[0].РазностьДат;
МассивПериодов = Новый Массив;
Интератор = РазностьДат - (РазностьДат * 2);
Пока Интератор <= 0 Цикл
Запрос = Новый Запрос(
"ВЫБРАТЬ
| НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(&ДатаНачало, МЕСЯЦ," + Интератор + "), МЕСЯЦ) КАК НачалоПериода,
| КОНЕЦПЕРИОДА(ДОБАВИТЬКДАТЕ(&ДатаНачало, МЕСЯЦ," + Интератор + "), МЕСЯЦ) КАК КонецПериода");
Запрос.УстановитьПараметр("ДатаНачало",ДатаНачало);
Выборка = Запрос.Выполнить().Выбрать();
Выборка.Следующий();
ЗаписьПериода = Новый Структура;
ЗаписьПериода.Вставить("НачалоПериода", Выборка.НачалоПериода);
ЗаписьПериода.Вставить("КонецПериода", Выборка.КонецПериода);
МассивПериодов.Добавить(ЗаписьПериода);
Интератор = Интератор + 1;
КонецЦикла;
Возврат МассивПериодов
КонецФункции ПоказатьПолучается вот что:
<p style="text-align: left; font-family: courier new,courier; color: blue">
<font color=red>Функция </font>РазбитьПериод<font color=red>(</font>ДатаНачало<font color=red>, </font>ДатаКонец<font color=red>)
</font>Запрос <font color=red>= Новый </font>Запрос<font color=red>;
</font>Запрос<font color=red>.</font>Текст <font color=red>=
</font><font color=black>"ВЫБРАТЬ
| РАЗНОСТЬДАТ(&ДатаНачало, &ДатаКонец, МЕСЯЦ) КАК РазностьДат"</font><font color=red>;
</font>Запрос<font color=red>.</font>УстановитьПараметр<font color=red>(</font><font color=black>"ДатаНачало"</font><font color=red>,</font>ДатаНачало<font color=red>);
</font>Запрос<font color=red>.</font>УстановитьПараметр<font color=red>(</font><font color=black>"ДатаКонец"</font><font color=red>,</font>ДатаКонец<font color=red>);
</font>Результат <font color=red>= </font>Запрос<font color=red>.</font>Выполнить<font color=red>().</font>Выбрать<font color=red>().</font>Следующий<font color=red>();
</font>РазностьДат <font color=red>= </font>Запрос<font color=red>.</font>Выполнить<font color=red>().</font>Выгрузить<font color=red>()[</font><font color=black>0</font><font color=red>].</font>РазностьДат<font color=red>;
</font>МассивПериодов <font color=red>= Новый </font>Массив<font color=red>;
</font>Интератор <font color=red>= </font>РазностьДат <font color=red>- (</font>РазностьДат <font color=red>* </font><font color=black>2</font><font color=red>);
Пока </font>Интератор <font color=red><</font><font color=red>= </font><font color=black>0 </font><font color=red>Цикл
</font>Запрос <font color=red>= Новый </font>Запрос<font color=red>(
</font><font color=black>"ВЫБРАТЬ
| НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(&ДатаНачало, МЕСЯЦ," </font><font color=red>+ </font>Интератор <font color=red>+ </font><font color=black>"), МЕСЯЦ) КАК НачалоПериода,
| КОНЕЦПЕРИОДА(ДОБАВИТЬКДАТЕ(&ДатаНачало, МЕСЯЦ," </font><font color=red>+ </font>Интератор <font color=red>+ </font><font color=black>"), МЕСЯЦ) КАК КонецПериода"</font><font color=red>);
</font>Запрос<font color=red>.</font>УстановитьПараметр<font color=red>(</font><font color=black>"ДатаНачало"</font><font color=red>,</font>ДатаНачало<font color=red>);
</font>Выборка <font color=red>= </font>Запрос<font color=red>.</font>Выполнить<font color=red>().</font>Выбрать<font color=red>();
</font>Выборка<font color=red>.</font>Следующий<font color=red>();
</font>ЗаписьПериода <font color=red>= Новый </font>Структура<font color=red>;
</font>ЗаписьПериода<font color=red>.</font>Вставить<font color=red>(</font><font color=black>"НачалоПериода"</font><font color=red>, </font>Выборка<font color=red>.</font>НачалоПериода<font color=red>);
</font>ЗаписьПериода<font color=red>.</font>Вставить<font color=red>(</font><font color=black>"КонецПериода"</font><font color=red>, </font>Выборка<font color=red>.</font>КонецПериода<font color=red>);
</font>МассивПериодов<font color=red>.</font>Добавить<font color=red>(</font>ЗаписьПериода<font color=red>);
</font>Интератор <font color=red>= </font>Интератор <font color=red>+ </font><font color=black>1</font><font color=red>;
КонецЦикла;
Возврат </font>МассивПериодов
<font color=red>КонецФункции
</font></p>
в чем может быть проблема?
В цикле формируем не запрос для получения каждого по отдельности элемента массива, а текст запроса.
Потом выгружаем запрос в таблицу, а из нее уже формируем массив.
Хотя для реальной задачи формировать массив нет необходимости: можно вернуть сразу таблицу.
Функция РазбитьПериод1(ДатаНачало, ДатаКонец)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РАЗНОСТЬДАТ(&ДатаНачало, &ДатаКонец, МЕСЯЦ) КАК РазностьДат";
Запрос.УстановитьПараметр("ДатаНачало",ДатаНачало);
Запрос.УстановитьПараметр("ДатаКонец",ДатаКонец);
РазностьДат = Запрос.Выполнить().Выгрузить()[0].РазностьДат;
МассивПериодов = Новый Массив;
Интератор = РазностьДат - (РазностьДат * 2);
Запрос = Новый Запрос;
Текст = "";
Пока Интератор <= 0 Цикл
Текст = Текст +
"ВЫБРАТЬ НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(&ДатаНачало, МЕСЯЦ," + Интератор + "), МЕСЯЦ) КАК НачалоПериода,
| КОНЕЦПЕРИОДА(ДОБАВИТЬКДАТЕ(&ДатаНачало, МЕСЯЦ," + Интератор + "), МЕСЯЦ) КАК КонецПериода
| ОБЪЕДИНИТЬ " + Символы.ПС;
Интератор = Интератор + 1;
КонецЦикла;
Текст = Лев(Текст,СтрДлина(Текст) - 14);
Запрос.Текст = Текст;
Запрос.УстановитьПараметр("ДатаНачало",ДатаНачало);
//
Выборка = Запрос.Выполнить().Выгрузить();
Для Каждого Строка Из Выборка Цикл
ЗаписьПериода = Новый Структура;
ЗаписьПериода.Вставить("НачалоПериода", Строка.НачалоПериода);
ЗаписьПериода.Вставить("КонецПериода", Строка.КонецПериода);
МассивПериодов.Добавить(ЗаписьПериода);
КонецЦикла;
Возврат МассивПериодов
КонецФункции ПоказатьА Действительно, к чему ?!
Вы уж меня простите, я немножко Ваши мысли в кучу соберу:
1. По условиям задачи, установленным ВАМИ:
далее Вы пишите:
Что то я в Ваших "стараниях" не увидел "функции разбивающей период времени с 1 по 14 сентября на отрезки, принадлежащие различным месяцам."
Может на калькуляторе попробуете?
2.
Да, особенно в Варианте 6. Я его пока читал все понял... Даже до конца не прочитал, а уже все понял.
А потом перешел к варианту 7 и 8 и ... бросил: легче самому нибудь придумать. Да еще и отладить нельзя. Замечательный "рефакторинг". А при разнице выполнения в милисекундах при 200 периодах ЧИТАБЕЛЬНОСТЬ ИМХО, будет являться ОСНОВНЫМ ПОКАЗАТЕЛЕМ УДАЧНОГО РЕФАКТОРИНГА. Включите мой вариант в голосование, там видно будет, чей читабельнее...
Ну и напоследок:
3. Я Вам Вас процитирую:
"Довольно неоднозначное и даже провокационное по своей форме решение" использование оператора Выполнить(), помещая в него текст с кодом, я бы назвал "порнографично".
Ваша статья: это бравада, "смотри как я умею, вот так умею, и так умею". И уж к рефакторингу она ТОЧНО не имеют НИКАКОГО отношения. На практике ни один вменяемый программист не будет использовать Ваш вариант №8.
1) берем вариант 2
2) добавляем две новые универсальный функции "НачалоПериода(Дата, Период)" и "КонецПериода(Дата, Период)" (аналоги функций из языка запросов)
3) получаем компактный, понятный и универсальный вариант
Функция НачалоПериода(Дата, Период)
Выполнить(СтрЗаменить("Возврат НачалоЧего(Дата)", "Чего", Период))
КонецФункцииТакже обратите, пожалуйста, внимание на вариант 5. Он кажется более громоздким, но это пример самоконтролируемой функции, записанной через требования к результату.
Ну и наконец, если Вас интересуют другие примеры сублимированного кода 1С, обратите внимание на .
Всё, что идёт после варианта №2, считаю деструктивным рефакторингом, здесь мне ближе позиция (2). Но это ИМХО, ничего личного.
Может, я и не прав, но для себя всегда отделяю рефакторинг от оптимизации. Соответственно, выработалось правило: если понимание кода другим разработчиком (большинством других разработчиков) усложняется - это деструктивный рефакторинг, и пользы от него нет, только вред.
Спасибо, на досуге почитаю.
при заданных датах с 1-го по 14-е сентября возвращает массив с одним элементом:
01.09.2013 00.00.00 - 31.09.2013.23.59.59,
все работает.
Что касается периода с 01.09.2000, действительно, результат был не корректен: спешил, писал, пракически без проверки.
Выкладываю исправленный вариант.
Функция РазбитьПериод(ДатаНачало, ДатаКонец)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РАЗНОСТЬДАТ(&ДатаНачало, &ДатаКонец, МЕСЯЦ) КАК РазностьДат";
Запрос.УстановитьПараметр("ДатаНачало",ДатаНачало);
Запрос.УстановитьПараметр("ДатаКонец",ДатаКонец);
РазностьДат = Запрос.Выполнить().Выгрузить()[0].РазностьДат;
МассивПериодов = Новый Массив;
Запрос = Новый Запрос;
Интератор = 0;
Пока Интератор <= РазностьДат Цикл
Запрос.Текст = Запрос.Текст +
"ВЫБРАТЬ НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(&ДатаНачало, МЕСЯЦ," + Интератор + "), МЕСЯЦ) КАК НачалоПериода,
| КОНЕЦПЕРИОДА(ДОБАВИТЬКДАТЕ(&ДатаНачало, МЕСЯЦ," + Интератор + "), МЕСЯЦ) КАК КонецПериода
| ОБЪЕДИНИТЬ " + Символы.ПС;
Интератор = Интератор + 1;
КонецЦикла;
Запрос.Текст = Лев(Запрос.Текст,СтрДлина(Запрос.Текст) - 14);
Запрос.УстановитьПараметр("ДатаНачало",ДатаНачало);
ТаблицаПериодов = Запрос.Выполнить().Выгрузить();
Для Каждого Строка Из ТаблицаПериодов Цикл
ЗаписьПериода = Новый Структура;
ЗаписьПериода.Вставить("НачалоПериода", Строка.НачалоПериода);
ЗаписьПериода.Вставить("КонецПериода", Строка.КонецПериода);
МассивПериодов.Добавить(ЗаписьПериода);
КонецЦикла;
Возврат МассивПериодов;
КонецФункции Показатьв результате чтения получилась небольшая таблица
мПер = РазбитьПериод0(Дата(1175,05,02),Дата(2213,11,15)); //320
мПер = РазбитьПериод1(Дата(1175,05,02),Дата(2213,11,15)); //225
мПер = РазбитьПериод2(Дата(1175,05,02),Дата(2213,11,15)); //160
мПер = РазбитьПериод5(Дата(1175,05,02),Дата(2213,11,15)); //310
мПер = РазбитьПериод6(Дата(1175,05,02),Дата(2213,11,15)); //300
мПер = РазбитьПериод7(Дата(1175,05,02),Дата(2213,11,15)); //210
мПер = РазбитьПериод8(Дата(1175,05,02),Дата(2213,11,15)); //85
мПер = РазбитьПериод9(Дата(1175,05,02),Дата(2213,11,15)); //85
Показатьв конце после комментария указано время в миллисекундах
результат от первого и последнего отличается в 3,8 РАЗА!! это поражает
хотя для себя я бы остановился на РазбитьПериод2 как выигрыш в два раза уже получен, а код ещё читабелен. результат 8 и 9 конечно отличный, но увидеть первый раз такой код в нем без "бутылки" не разобраться.
Ты не одинок, тоже страдаю периодически =) Ниже мой велосипед начала 90-х. Задача для cебя была - минимум строк на BASIC-е. Сейчас смотрю с ужасом =)
10 INPUT "АРАБСКОЕ ЧИСЛО: "; А$
20 FOR I=0 TO LEN(A$)-1
30 X=VAL(MID$(A$,LEN(A$)-I,1))
40 IF X=4 OR X=9 THEN B$=MID$("IXCM",I+1,1)+MID$("VXLCDM",I*2+(X+1)/5,1)+B$
50 IF X<4 THEN B$=MID$("IIIXXXCCCMMM",1+I*3,X)+B$
ELSE IF X>4 AND X<9 THEN B$=MID$("VLD",I+1,1)+MID$("IIIXXXCCCMMM",1+I*3,X-5)+B$
60 NEXT I
70 PRINT "РИМСКОЕ ЧИСЛО: "; B$
Было легко читать, легко расширить, легко отладить.
Дальше пошли крайности. Да так тоже будет работать, но это неприемлемо. Трудно читать, трудно сопровождать и чтобы отладить - придется модифицировать код. Я бы не заострил своё внимание, если не комментарии автора. Он уверен что так нужно делать.
Увидев у своих кодеров что-то похожее на варианты старше 4, они бы рисковали стать безработными, пока получали по ушам.
Автору хочется пожелать повзрослеть. Наконец понять что программирование - такое же, местами кстати тупое, вкалывание, как работа экскаваторщика. Рано или поздно ты прекратишь заниматься научной мастурбацией, это у всех взрослых дядек проходит.
Мои уважаемые коллеги. Помните что ваш код вы можете не вспомнить через пару лет. Пишите понятно. "Крутые" программисты конечно нужны, однако "круто" написанный код - не нужен вообще никому. Если где-то вам пришлось до оптимизироваться до таких ужасов, скорее всего у вас проблемы с архитектурой проекта.
И я практиковал ассемблер. В ваших байтах по сколько бит бывало? ;-) C,Cpp,Delphi,php,python,java,js etc etc.. не просто знаю кучу страшных слов, а реально умею ими работу работать. В данный момент практикую с микроконтроллерами. Знаешь, даже с ними уже нет проблем, когда не влазит байт, или даже килобайт. Памяти много и она дешевая.
В статье я предложил 10 приемов для использования не всегда всех вместе, а каждого при необходимости и с оговоркой рисков. В комментарии (18) я уже написал
Вы можете заказать платную консультацию или разработку у автора. Будет создан приватный заказ на «Бирже заказов» для автора.
№ 158625
Создание 06.09.13 13:14
Обновление 11.09.13 14:02
Просмотры 29929
Загрузки 4
Рейтинг
53
Комментарии 53
Код открыт Не указано
Рубрики Рефакторинг и качество кода
Кому Разработчик
Тип файла Внешний отчет (ert,erf)
Платформа 1С:Предприятие 8
Конфигурация 1C:Бухгалтерия
Операционная система Не имеет значения
Страна Не имеет значения
Отрасль Не имеет значения
Налоги Не имеет значения
Вид учета Не имеет значения
Доступ к файлу Абонемент ($m)