![]() |
|
Модераторы: Akina |
![]()
|
|
| Andrei_V |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 5 Регистрация: 28.8.2007 Репутация: нет Всего: нет |
Имеются таблицы (для простоты структура таблиц сокращена)
1 таблица "ack_cdr" (данные о телефонных звонках): Кому - тип текстовый (набранный номер, например "83425651357") Длительность - числовой (длительность разговора в секундах, например 36) 2 таблица "ТЛФ - Коды" (коды городов): префикс - тип текстовый (префикс города, куда был звонок, например "8342") тарифная зона - тип текстовый (тарифная зона, к которой относится префикс, например "Россия 2") 3 таблица "ТЛФ - Зоны" (тарифные зоны): тарифная зона - тип текстовый (тарифная зона, например "Россия 2") тариф - тип числовой (стоимость в руб минуты звонка в эту зону, например 5) Надо провести обработку файла cdr и определить стоимости звонков. Проблема в том, что в таблице codes есть префиксы 8342 - пермская область и 8 - россия Причем префиксы имеют произвольную длину - от 1 до 6 символов Если делать выборку конструктором с условием выборки WHERE ((ack_cdr.[Длительность])>0) AND ((ack_cdr.Кому) Like [ТЛФ - Коды].[Префикс] & "*") то, например звонок на номер "83425651357" тарифицируется дважды: как "8 - россия" и как "8342 - пермская область". Разумеется такой звонок надо протарифицировать только по префиксу с максимальной длиной (т.е. по "8342"). Как написать запрос, чтобы обработка проводилась по префиксу максимальной длины? Заранее благодарен за подсказки. |
|||
|
||||
| kapbepucm |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 993 Регистрация: 14.6.2007 Где: Латвия Репутация: нет Всего: 12 |
Следующий шаг, сделать группировку по номеру, где Len(вытащенного_префикса) максимален.
Это сообщение отредактировал(а) kapbepucm - 28.8.2007, 08:57 -------------------- (С) kapbepucm |
|||
|
||||
| Andrei_V |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 5 Регистрация: 28.8.2007 Репутация: нет Всего: нет |
Слишком общий совет.
|
|||
|
||||
| Akina |
|
||||
|
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 30 Всего: 454 |
Значит, надо производить разделение номера на префикс и собственно локальный номер, выравнивать отделенный префикс и префикс из справочника пробелами до максимально возможной длины, и затем связывать уже по этому вычисляемому полю.
В случае MS Access - для этого придется использовать отдельный подзапрос. -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
||||
|
|||||
| Andrei_V |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 5 Регистрация: 28.8.2007 Репутация: нет Всего: нет |
||||
|
||||
| Akina |
|
|||
|
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 30 Всего: 454 |
Если ты не можешь написАть вменяемый алгоритм отделения префикса от номера - не проси этого от программы. И вообще - пока нет алгоритма, код писАть бессмысленно. Программа - дура, и делает только то и так, что и как ты ей сказал делать.
А что, есть звонки, где "8", а потом сразу номер? -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
| kapbepucm |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 993 Регистрация: 14.6.2007 Где: Латвия Репутация: нет Всего: 12 |
C алгоритмом помочь?
Это сообщение отредактировал(а) kapbepucm - 29.8.2007, 10:37 -------------------- (С) kapbepucm |
|||
|
||||
| bopoha |
|
||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1283 Регистрация: 10.5.2006 Где: Беларусь, Минск Репутация: 21 Всего: 21 |
kapbepucm,
Я в шоке! Все намного проще.
Основной тормоз тут MoveLast после открытия. И еще, зачем эта функция? Походу такое можно и в запрос засунуть. Andrei_V, Под "определить стоимости звонков" понимается записать в поле какой-то таблицы сумму. То получается, что посчитать это будет проще процедурой VBA, чем зарпосом (При его помощи можно оптимизировать вычисления). Тарифы телефонных кодов можно закешировать (Collection или Recordset статический) - летать будет .
Почему это сложность? Если в цикле обрабатывать номера, то можно делать разбор номера по шаблону.
Примерный алгоритм: 1. Цикл по номерам 1.1. Выделить из номера код 1.2. Получить тариф звонка 1.3 Расчитать стоимость ..... Это сообщение отредактировал(а) bopoha - 29.8.2007, 23:54 |
||||||
|
|||||||
| kapbepucm |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 993 Регистрация: 14.6.2007 Где: Латвия Репутация: нет Всего: 12 |
Частично взяв идеи bopoha, коррекция (хотя я предупреждал, что вариант неидеальный):
To bopohaБыл у меня случай, где я долго искал ошибку (там этим способом определялось количество записей, но Recordset другого типа, естественно), так теперь это, как рефлекс
Это сообщение отредактировал(а) kapbepucm - 30.8.2007, 09:29 -------------------- (С) kapbepucm |
||||
|
|||||
| bopoha |
|
||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1283 Регистрация: 10.5.2006 Где: Беларусь, Минск Репутация: 21 Всего: 21 |
Вариант номер 1.
На открытие таблицы тратится куча времени! Где-то перед задолго до многочисленного вызова функции откываем набор как статический (т.е. все данные читаем в память):
Если оставаться при предыдущем варианте следовало бы открывать как dbOpenForwardOnly - для прохода один раз. Вариант номер 2. Если исходить из того факта, что нужны не все коды. Их в таблице гораздо больше, чем сравниваемых. То: В.2.1. Отфильтровать набор при открытии по возрастанию кодов. Перед поиском находить запись по первой цифре искомого номера. В.2.1. Открывать набор в функции с фильтром по первой цифре номера (или минимальному количеству цифр). Это не объясняет назначение функции. Меня интересует что она даст? Зачем она? Т.е. подразумевается ответ: "Функция получает ... находит .... и возвращает ....". На тему статического набора я пример привел. По поводу Collection
При этом нужно учитывать что Collection находится в памяти и не стоит туда загянять очень много. Естественно все это будет работать при вычислении в коде. |
||||||
|
|||||||
| Andrei_V |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 5 Регистрация: 28.8.2007 Репутация: нет Всего: нет |
Номера все имеют вид 8-код_города_номер. Но дело в тарифах. Например (очень упрощенно): 83422 - 1 руб/мин 83512 - 2 руб/мин остальная 8 - 3 руб/мин Как-то не силен я пока код писать в MS Access. До сих пор делал все конструкторами - таблицы, запросы, отчеты. Большего не требовалось. И мне казалось, что и мою задачу можно решить не прибегая к непосредственному написанию кода на VB. Функция-то ясна. Сам был программистом, правда лет 10 назад. |
|||
|
||||
| kapbepucm |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 993 Регистрация: 14.6.2007 Где: Латвия Репутация: нет Всего: 12 |
To bopohaСлучай был подобным:
To Andrei_VА где и как данные будут выводится (вырисовывается 2 варианта: лёгкий, но тормознутый; и более сложный, но быстро летающий)? Это сообщение отредактировал(а) kapbepucm - 31.8.2007, 13:14 -------------------- (С) kapbepucm |
|||
|
||||
| Akina |
|
||||
|
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 30 Всего: 454 |
ДЛя ускорения работы надо использовать
Тогда можно просто бежать по рекордсету до первого совпадения - все следующие будут с заведомо более коротким префиксом. И не потребуется использования Like - можно сразу
-------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
||||
|
|||||
| Andrei_V |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 5 Регистрация: 28.8.2007 Репутация: нет Всего: нет |
||||
|
||||
| bopoha |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1283 Регистрация: 10.5.2006 Где: Беларусь, Минск Репутация: 21 Всего: 21 |
До меня дошел алгоритм поиска тарифа за код:
Начинать поиск нужно с самого длинного кода (84320), если не найден убрать одну цифру ((84320) поискать. Если опять не нашли повторить. Правильно? Очень рекомендую разобраться с VBA, такое просто запросами тяжеловато. 1. Можно отдельной функцией реализовать выше указанный алгоритм и в запросе вызывать ее, передвая функции код. Это очень медленный вариант. 2. Либо программно все сделать. Это вариант будет быстрее. Ничего сложного в этом нет. |
|||
|
||||
![]()
|
| Правила форума "MS Access" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Akina. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | MS Access | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |