Решение ДЗ №13 базового курса
Решение первого задания по расчету.
К сожалению, у Вас недостаточно прав для просмотра этой записи. Если Вы еще не залогинены на сайте — залогиньтесь. Если Вы оплачивали курс, у Вас активирован токен доступа, Вы залогинены, но Вы видите эту запись — напишите нам на e-mail поддержки.
Выполнено
А если добавить в регистр дополнительное измерение Год (или месяц , в зависимости от задачи)? Тогда проблемы вообще никакой нет. Или добавление лишнего измерения ради операции заполнения графика не оправдано?
Для задачи заполнения расширять структуру регистра кажется не правильным.
Более того, теоретически график может заполняться с 18.11.2009 по 23.02.2010.
Не всегда. Например, в БД данные за 10 лет, а перезаполнить надо данные за неделю.
Способ 1:
1. Выгрузить запросом записи в ТаблицуЗначений, при этом по условию отсечь записи с датами относящимися к периоду заполнения.
2. В цикле добавить в ТаблицуЗначений строки с датами периода заполнения.
3. Выгрузить ТаблицуЗначений в НаборЗаписей.
3. Записать НаборЗаписей с замещением существующих записей.
Способ 2:
1. Получить запросом Выборку ключей регистра для периода заполнения.
2. В цикле обхода Выборки удалить записи из регистра МенеджеромЗаписи.
3. Создать пустой НаборЗаписей и заполнить данными периода заполнения.
4. Записать НаборЗаписей без замещения существующих записей.
Способ 2 более тяжелый из-за удаления записей МенеджеромЗаписи, но зато не перезаписываются записи за все периоды существующие в базе данных.
Способ 2 очень тяжелый.
Способ 1 принимается.
Задание выполнил
Евгений, если не сложно при выкладывании решения по 14 заданию заполните свойство – Ведущие для предопределенных видов расчета, а то я слегка запутался, наставил галочек и конфигуратор , стал ругаться. Я переставил, конфигуратор не ругается, но не знаю правильно ли.
Ок :)
А что если выгрузить набор записей в Таблицу Значений, в которой есть метод НайтиЗначение, а потом НаборЗапией.Загрузить(). Мне кажеться мы избежали бы кучу нюансов.
Или я в чем то ошибаюсь?
Да, с таблицей значений можно было бы решить задачу.
Как вам такое решение без циклов:
Процедура СформироватьГрафик(ДатаНачала, ДатаОкончания, ВыходныеДни, ТипГрафика)
Запрос = Новый Запрос;
Запрос.Текст = “ВЫБРАТЬ
ГрафикиРаботы.ТипГрафика,
ГрафикиРаботы.Дата,
ВЫБОР КОГДА ДЕНЬНЕДЕЛИ(ГрафикиРаботы.Дата) В (&ВыходныеДни)
ТОГДА 0 ИНАЧЕ 1 КОНЕЦ КАК Значение
ИЗ
РегистрСведений.ГрафикиРаботы КАК ГрафикиРаботы
ГДЕ
ГрафикиРаботы.ТипГрафика = &ТипГрафика
И ГрафикиРаботы.Дата >= &ДатаНачала
И ГрафикиРаботы.Дата <= &ДатаОкончания
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ГрафикиРаботы.ТипГрафика,
ГрафикиРаботы.Дата,
ГрафикиРаботы.Значение
ИЗ
РегистрСведений.ГрафикиРаботы КАК ГрафикиРаботы
ГДЕ
ГрафикиРаботы.ТипГрафика = &ТипГрафика И
(ГрафикиРаботы.Дата &ДатаОкончания)”;
Запрос.УстановитьПараметр(“ТипГрафика”, ТипГрафика);
Запрос.УстановитьПараметр(“ДатаНачала”, ДатаНачала);
Запрос.УстановитьПараметр(“ДатаОкончания”, ДатаОкончания);
Запрос.УстановитьПараметр(“ВыходныеДни”, ВыходныеДни); // Выходные дни – это массив, например (6, 7)
Набор = РегистрыСведений.ГрафикиРаботы.СоздатьНаборЗаписей();
Набор.Отбор.ТипГрафика.Установить(ТипГрафика);
Набор.Загрузить(Запрос.Выполнить().Выгрузить());
Набор.Записать();
КонецПроцедуры // СформироватьГрафик()
Всё работает. Первый запрос формирует записи по выбранному периоду, второй выбирает записи “как есть”. Отбор можем наложить только на график, поэтому всё равно надо вытаскивать все записи.
Нет, не получилось. Ладно, вместо языка запросов попробуем на “великом и могучем”:
(ГрафикиРаботы.Дата МЕНЬШЕ &ДатаНачала
ИЛИ ГрафикиРаботы.Дата БОЛЬШЕ &ДатаОкончания)
Идея с запросом интересная.
Только что будет, если график изначально пустой. Что вернет запрос?
Да, вечером сообразил, что тут мой косяк. Проверял ведь на заполненном регистре сведений :) Но от своей идеи не отказываюсь. По периоду обработки заполняем таблицу значений датами периода. Потом её инспользуем как временную таблицу в первом запросе. Остальное дело техники – дата есть, график берём из параметра, день недели вычисляем. С утра на свежую голову сделаю.
Правильно говорят “утро вечера мудренее” :) Сегодня решил задачу двумя способами:
1. Без временной таблицы. Оставляем только нижний подзапрос, выбирающий записи вне периода. Результат загружаем в набор записей, далее дописываем записи по выбранному периоду уже без всяких проверок.
Код занял 30 строк.
2. С временной таблицей. Верхняя часть запроса:
ВЫБРАТЬ ТЗ.Дата
ПОМЕСТИТЬ ТаблицаДат
ИЗ &ТЗ КАК ТЗ;
ВЫБРАТЬ
&ТипГрафика КАК ТипГрафика,
ТаблицаДат.Дата,
ВЫБОР КОГДА ДЕНЬНЕДЕЛИ(ТаблицаДат.Дата) В (&ВыходныеДни) ТОГДА 0 ИНАЧЕ 1
КОНЕЦ КАК Значение
ИЗ ТаблицаДат
ОБЪЕДИНИТЬ ВСЕ
… далее без изменений.
Но здесь сначала надо собрать ТЗ из одной колонки по датам. Код занял 50 строк.
Обойтись без циклов, ува не получилось – фокус не удался :) Первый вариант мне нравится больще, он более компактный и наглядный.
Замечательно.
Все-таки, мне кажется вариант без циклов есть. Но оставим этот вопрос до продвинутого курса.
Думал над вариантом без циклов – “не выходит каменный цветок” :) Это же надо как-то “уговорить” запрос выдать таблицу по датам периода, при этом ни на одну реальную таблицу мы опереться не можем. Смотрел ключевое слово ПЕРИОДАМИ – но это для итогов. Если в продвинутом курсе как-то получится без циклов, будет очень интересно.
Получится :)
Добрый вечер. При решении момента с обработкой заполнения графика я в отладчике открыл табло и в нем просмотрел Набор.Отбор.Дата – у этого элемента отбора есть поля ЗначениеС и ЗначениеПо. и если их заполнить:
Набор.Отбор.ТипГрафика.Установить(ТипГрафика);
Набор.Отбор.Дата.значениеС = ДатаНачала;
Набор.Отбор.Дата.ЗначениеПо = ДатаОкончания;
Набор.Прочитать();
то достаточно одного цикла по дням выборанного периода. Я потестировал подобное решение и ошибок вроде не заметил. Является ли такой вариант возможным для использования в решении?
Добрый!
Да, это вариант. Но и при таком отборе нужно учитывать, что набор может быть заполнен частично.
То есть общая схема решения останется такой же, но количество итераций вложенного цикла уменьшится.
А зачем это учитывать? А если после отбора и прочтения набора Набор.Очистить()
и потом заполнить? В этом случае нет разницы был ли он заполнен частично.
Соглашусь, ваше решение принимается!
Признайтесь, Вы точно тестировали это решение? У Вас не хватает двух строк:
Набор.Отбор.Дата.Использование = Истина;
Набор.Отбор.Дата.ВидСравнения = ВидСравнения.ИнтервалВключаяГраницы;
Но скажу честно – это тоже не сработает. Всё очень просто – для набора записей регистра сведений отбор может устанавливаться только на равенство. В синтакс-помощнике даже стоит Важно!
Слона то мы и не заметили ))
Спасибо, Константин.
Полностью согласен – больше часа потратил на “тестирование” особенно долго доходил до
Набор.Отбор.Дата.ВидСравнения = ВидСравнения.ИнтервалВключаяГраницы;
P.S.: Зачем писать – Я потестировал подобное решение и ошибок вроде не заметил.
P.P.S.: Или как моно тестировать чтоб – ошибок вроде не заметил. ;))
А у меня так не получилось, отбор по интервалу не устанавливается. Т.е. после набор.прочитать Возвращается набор за все даты. И в помошнике в описании написано:”Содержит левое значение сравнения, если в качестве вида сравнения используется интервал” – вроде и не должно работать. Как Вам удалось, тоже хочется чтобы получилось
Как мы выяснили, предложенный способ не работает..