Имя: Пароль:
1C
1С v8
[Решено] Нужна идея, как лучше реализовать перебор таблицы и сравнивать её с другой
0 Vladal
 
25.06.15
09:58
Есть основная таблица значений, которую уже обработал пользователь. В ней содердится номенклатура и цена.
Есть вторая таблица значений, в которой есть две колонки, содержащие диапазон цен - Нижний предел и Верхний предел.

Вторая таблица выглядит примерно так:

Текст = "
|Наименование   НижнийПредел   ВерхнийПредел
|Диапазон1           0.01         1000.00  
|Диапазон2        1000.01         5000.00
|Диапазон3        5000.01       999999999999

Необходимо по цене из первой таблицы найти ее вхождение в диапазон, описанный во второй таблице.

Я предполагаю такие варианты:
- пройти циклом по первой таблице, сравнивая значение колонки цены со строками таблицы диапазонов; (самый очевидный, но менее эффективный)
- запулить обе таблицы в запрос, пусть эти занимается движок запросов;
- типовой процедурой ОбщегоНазначения.ОтобратьСтрокиПоКритериям для каждого диапазона выбрать соответствия из основной таблицы и уже порциями их обработать.

Первый способ, думаю, самый ресурсоёмкий.
Может какие другие идеи есть?
1 fisher
 
25.06.15
10:03
Первый способ самый оптимальный. С учетом того, что диапазонов вряд ли может быть много, алгоритм отработает быстро даже на мобильном телефоне.
Городить серверные вызовы с сериализацией туда-сюда и запросами - абсолютно лишнее. Даже если это серверный алгоритм - ломиться на сервер БД для такой простейшей вещи это оверкилл.
2 vde69
 
25.06.15
10:04
если база серверная - то запросом
если база файловая - http://wiki.mista.ru/doku.php?id=1c:v8:howto:algoritm_sravnenija_dvux_tablic_po_tekstovomu_polju
3 vde69
 
25.06.15
10:08
кстати вторую таблицу если она не большая можно преобразовать в условие запроса "Где"
4 fisher
 
25.06.15
10:13
(1) + Если в таблица диапазонов большая, то можно двоичным поиском.
5 zenik
 
25.06.15
10:15
Я бы сперва прошелся по таблице 2, сформировал таблицу 3 вида: Наименование, СтрокаНачалаДиапазонаТ2, СтрокКонцаДиапазонаТ2. т.е. сформировать некий индекс, определяющий строки диапазона для каждого наименования. Потом цикл по первой таблице, с поиском наименования в 3-й и перебором диапазона из второй, но уже по заранее известным строкам. Понятно объяснил?
6 marvak
 
25.06.15
10:15
(0)
А запросом может?
Первую таблицу соединить со второй по условию вхождения цены в интервал?
7 Serg_1960
 
25.06.15
10:19
Если вторая таблица небольшая, то можно обойтись вообще без соединений. Например, сформировать текст запроса циклом по второй таблице с формированием текста запроса типа "ВЫБОР КОГДА... ИНАЧЕ...КОНЕЦ КАК Диапазон"
8 Гёдза
 
25.06.15
10:19
(3) Проще соединение, а не через где
9 Vladal
 
25.06.15
10:20
Таблица диапазонов из трех строк. Максимум 4 (это политика ценнобразования компании)

(3) Можно и так
(6) Да. Я про этот вариант запросом и думал.
(5) Я предполагаю так:
выбрать каждый диапазон и применить его к основной таблице. Получу массив строк, удовлетворяющий условию НижнийИнтервал..ВерхнийИнтервал
10 ам794123
 
25.06.15
10:23
(0) это стандартная задачка из экзамена специалист по платформе
11 marvak
 
25.06.15
10:26
(9)
Запросом с соединением делай, типа
ВЫБРАТЬ
....
   ПерваяТаблица.Номенклатура,
   ПерваяТаблица.Цена,
   ВтораяТаблица.Наименование  
ИЗ
   ПерваяТаблица
ЛЕВОЕ СОЕДИНЕНИЕ
   ВтораяТаблица
ПО
   (ПерваяТаблица.Цена <= ВтораяТаблица.ВерхнийПредел)
   И (ПерваяТаблица.Цена >= ВтораяТаблица.НижнийПредел)
12 fisher
 
25.06.15
10:40
Я смотрю, это массовое заболевание - любые итерации заменять запросом к серверу БД. Я так понимаю, уверенность в том, что это быстрее и оптимальней базируется на оптической иллюзии количества элементарных операций. Там цикл (много), а там типа одна (запрос).
Сабжевую таблицу диапазонов, кстати, можно вообще упорядоченным одномерным массивом представить.
13 Гёдза
 
25.06.15
10:42
(12) Ты просто предлагаешь нестед лукап делать в циклах в коде 1с
14 Гёдза
 
25.06.15
10:44
(12) Или ты еще предлагаешь бинарный поиск делать в массиве из 3 элементов?
15 fisher
 
25.06.15
10:51
(13)(14) И что в этом плохого в данном случае?
Хотя, если сабжевый алгоритм исполняется на сервере - то хрен с вами. Погоды не сделает.
Просто с таким же подходом и на тонкий клиент лезут. Вместо простейшего быстрого алгоритма фигачат лишние серверные вызовы.
16 Ildarovich
 
25.06.15
11:18
Есть другая идея:
1) объединить две таблицы (дописать вторую в хвост первой), совместив колонки цена и нижний предел; выбросив колонку верхний предел, добавив колонку НаименованиеДиапазона;
2) отсортировать полученную таблицу по цене;
3) пробежаться по полученной таблице, присваивая колонку "НаименованиеДиапазона" на пустые места вниз.
17 Vladal
 
25.06.15
11:23
(16) Хорошая идея, но я в ней сомневаюсь. Мне бы только найти соответствие таблицы диапазонов по цене из первой таблицы, потому как там дальше начинается пир по другим колонкам таблицы диапазонов, которые я не привёл.
18 Мыш
 
25.06.15
11:28
Сортировать обе таблицы по цене/верхнему диапазону.
Из второй таблицы берем соответствие для условия.
Перебор первой таблицы по условию "если меньше то истина".
Как только ложь - убираем лишнее условие из соответствия, чтоб лишнего не перебирать.
19 Vladal
 
25.06.15
11:59
(18) Тоже интересная мысль.
20 Vladal
 
25.06.15
12:00
только потом придется назад сортировать по группировкам номенклатуры/документов и т.п. Или хранить две ТЗ - оригинал и отсортированную, и сопоставлять одну с другой. Муторно и ресурсоёмко.
21 Гёдза
 
25.06.15
12:02
(16) Это ты мердж джойн сейчас описал )))
22 Мыш
 
25.06.15
12:07
(20) В исходной постановке не было требования сохранять сортировку )
23 palpetrovich
 
25.06.15
12:42
(0) модернизировать "- пройти циклом по первой таблице..."
сортируем втрорую, анализируем на вхождение "с середины" по ВерхнийПредел, движемся вниз или вверх, соответсвенно до получения результата  :)
24 Vladal
 
25.06.15
16:03
Решил просто:

// Поиск строки интервала в матрице цен
СтрокаМатрицыЦен = ОбщегоНазначения.ОтобратьСтрокиПоКритериям(МатрицаЦен,
    Новый Структура("НижнийПредел, ВерхнийПредел", НоваяСтрока.Цена, НоваяСтрока.Цена),
    Новый Структура("НижнийПредел, ВерхнийПредел", ВидСравнения.МеньшеИлиРавно, ВидСравнения.БольшеИлиРавно)).Выгрузить();
Компьютер — устройство, разработанное для ускорения и автоматизации человеческих ошибок.