v7. Задачка по программированию. НайтиЭлементПоДате(Спр, ДатаДок)

Автор Пиит, 16 апреля 2024, 12:33

« назад - далее »

Пиит

В школе, на уроках математики, наша Классная всегда заставляла решать задачки несколькими способами. Прямо одержимость какая-то была. Решили вроде, ан нет, давай ещё, покрути, посмотри под другим углом, возьми другую ручку. Бывало, проверяет домашку, шесть человек у досок стоят, мелом чиркают, две доски у нас было на это дело, целый урок могли посвятить таким разборкам, и всем Классом выбирали лучшее решение. Спасибо, Валентина Владимировна, долгих лет, научила главному - коли решил, не останавливайся, может есть другой способ, по-красивше. Именно так, по-красивше. В математике, как оказалось, тоже есть своя красота.

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

Дано: обычный справочник, код и наименование не существенно, как и прочие реквизиты, но есть в ём важный реквизит ДатаЗнач типа Дата, с сортировкой, и дана переменная ДатаДок типа Дата. Значения ДатаЗнач в справочнике уникальны.
Найти: метод, позволяющий найти элемент в данном справочнике, по аналогии с методом объекта Периодический.НайтиЗначение(ДатаДок), т.е. если в справочнике есть Элемент со значением ДатаЗнач = ДатаДок, вернуть этот Элемент, если нет, предыдущий элемент в порядке ДатаЗнач, либо следующий за ним, на ваш выбор. Количество итераций есть конечная величина и уж точно меньше чем 99 999 999.

АЛьФ

Навскидку как-то так:

SELECT TOP 1 врем.ID [Элемент $Справочник.Некий]
FROM
(
SELECT спр.ID
FROM $Справочник.Некий спр
WHERE $спр.ДатаЗнач >= :ДатаГраницы
ORDER BY $спр.ДатаЗнач, спр.ID
) врем

Знак сравнения в WHERE подставляем в зависимости от того нужен предыдущий или следующий.

trad

правильно так:
SELECT TOP 1
 спр.ID [Элемент $Справочник.Некий]
FROM $Справочник.Некий спр
WHERE $спр.ДатаЗнач >= :ДатаГраницы
ORDER BY $спр.ДатаЗнач, спр.ROW_ID

Пиит

Вот, демоны ))))

Забыл главное сказать, без внешних компонент  )))


Уже поди забыли, что такое бывает )

trad

Зачем без ВК если известно, что иные способы хуже?

а СоздатьОбъект("ADODB.хххх") - это уже запрещенка или еще нет?

Пиит

Цитата: trad от 16 апреля 2024, 13:53это уже запрещенка или еще нет

Есть такая группа задач в геометрии - задачи на построение, где у вас есть только линейка и циркуль.
Вот и здесь, только линейка и циркуль. ))
Только непосредственно методы 1Сv7 как есть в учебнике "Описание встроенного языка".

ЗЫ: один чел даже доказал теорему, что все задачи на построение, которые подлежат решению, можно решить только с помощью циркуля )

Пиит

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

АЛьФ

Тогда так, наверное:
Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса = 
"
|Элемент = Справочник.Некий.ТекущийЭлемент;
|ДатаЗнач = Справочник.Некий.ДатаЗнач;
|Группировка ДатаЗнач;
|Группировка Элемент;
|Условие(ДатаЗнач >= ВыбДата);
|";
Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
	Возврат;
КонецЕсли;

Если Запрос.Группировка(1) = 1 Тогда
	Если Запрос.Группировка(2) = 1 Тогда
		Сообщить(Запрос.Элемент);
	КонецЕсли;
КонецЕсли;

Пиит

Цитата: АЛьФ от 16 апреля 2024, 14:34" |Элемент = Справочник.Некий.ТекущийЭлемент; |ДатаЗнач = Справочник.Некий.ДатаЗнач; |Группировка ДатаЗнач; |Группировка Элемент; |Условие(ДатаЗнач >= ВыбДата);

Эх, всё после каникул забыли, когда последний раз Запрос писали?

Этот вариант уже можно зафиксировать для истории?

АЛьФ

Цитата: Пиит от 16 апреля 2024, 14:43
Цитата: АЛьФ от 16 апреля 2024, 14:34" |Элемент = Справочник.Некий.ТекущийЭлемент; |ДатаЗнач = Справочник.Некий.ДатаЗнач; |Группировка ДатаЗнач; |Группировка Элемент; |Условие(ДатаЗнач >= ВыбДата);

Эх, всё после каникул забыли, когда последний раз Запрос писали?

Этот вариант уже можно зафиксировать для истории?

Уже лет 15 с черными запросами только эпизодически сталкиваюсь. Все сейчас тут пишу с ходу. Для нормального решения надо тестовый полигон делать.

Пиит

Цитата: АЛьФ от 16 апреля 2024, 14:50Уже лет 15 с черными запросами только эпизодически сталкиваюсь

А у меня обратный прикол. Сто лет назад написал на Запросе уни ПоискПоВхождению слова, отлизал как мог в отладчике, портянки замеров, и забросил. На фаловых базах оценка неуд, от 10-ти секунд и более. А вот относительно недавно попробовал на огромной базе, sql, и ёкнул, за 2 сек, не больше, справляется.

не хуже прямых запросов!

Пиит

Трудно на запросах, хоть каких, количество итераций оценить, без знаний о запросе.

Пиит

Сразу скажу, что решения я не знаю, идеи есть, но пока так себе.
Делал раньше тоже запросом, но с хитрецой.

Это чтобы вы не подумали, что я тут издеваться над кем-то вздумал.
Олимпиада эта и для меня тоже.

Djelf

Цитата: АЛьФ от 16 апреля 2024, 14:50Для нормального решения надо тестовый полигон делать.
Вот именно! А делать тестовый полигон, да еще каждому участнику, это зачем такая нагрузка на всех? Давайте тестовую базу!

Запрос можно, но лучше сначала проверить по НайтиПоРеквизиту или отдельным запросом на точное равенство.
А уже потом делать длительный запрос.
Но если по условию задачи только дата, то любая оптимизация даст почти 0й прирост в скорости.

Пиит

Давайте положим, что количество элементов, обработанных в запросе + все циклы по обработке запроса = количество итераций.