Форумы HiProg.com - MS ACCESS, VBA, VB

 

Ответить на сообщение

Вернуться к теме

Вы отвечаете на сообщение:

ник: Explorer
много сломано копий вокруг такой задачи как указание фэйкового (Fake) порядкового номера записи для номерации строки запроса. Во всех специализированных форумах гуру разработки приложений БД постоянно подтрунивают над новичками.

<skiped>

в общем количество аргументов говорящих не в пользу таких решений весьма велико, тем не менее в ряде случаев такая нумерация просто необходима и весьма удобна.

предположим (может излишне смелое предположение, но для меня регулярная ежедневная задача) у вас есть файл EXCEL содержащий 2-7-10'000 записей о событиях - на листе по порядку перечислены:


   DATE   |   PLACE   |   RATE
----------+-----------+----------
 12/09/06 |   1       |   1.00
 12/09/06 |   0       |   1.07
 12/09/06 |   3       |   1.88
 17/09/06 |   0       |   1.00
 17/09/06 |   2       |   1.13
 18/09/06 |   1       |   1.43
 19/09/06 |   4       |   1.99
 19/09/06 |   1       |   1.75
 19/09/06 |   0       |   1.08
 19/09/06 |   2       |   1.03
 19/09/06 |   3       |   1.56
 20/09/06 |   1       |   1.98
 20/09/06 |   0       |   1.77


для документа Excel таая структура вполне нормальна - последовательность события определяется порядком записи. Имея такую таблицу легко расчитать, например сумму с накопленным итогом или среднее отклонение коэффициента на дату или накопленный результирующий коэффициент на дату или на каждое следующее событие (сумма нарастающим итогом например)

при чем в Excel это решается легко и непринужденно - там к предыдущей ячеке можно обратиться явно, чего не скажешь про решение в Access - сто вопросов в форумах - как посчитать значение "Текущая запись" + "Предыдущая запись"? а если нарушен порядок сортировки? а если в таблице есть пропущенные значения?

Кроме того, и об этом новичкам говорят постоянно - принцип хранения и сортировки данных в Access и в Excel (в DataBase и SpreadSheet) совершенно различен - и то, что кажется само собой разумеющимся в одном случае не будет работать или даст неверный результат в другом - будет нарушена последовательность счетчика при пересортировке, например, или Агрегатные функции вообще не будут работать...

в некоторых случаях можно сначала экспортировать даные из Excel в таблицы Access одновременно присваивая им идентификаторы или уже после экспорта данных модифицировать таблицу Access добавив поле счетчика (это совершенно разные подходы) записи получат уникальный идетификатор и с ними можно будет работать точно так как с любыми другими массивами данных в Acces обращаясь к полям записи в запросе.

но это может оказаться слишком хлопотно и громоздко - какой смысл экспортировать данные, если нужно всего три секунды на то, чтобы их обработать, агрегировать, извлечь информацию и выкинуть. (даже не упоминая о потоянно пухнущей при этих операциях базе - которую придется постоянно сжимать и сбрасывать счетчики Autoincrement).
А если в исходной таблице 65536 записей? например данные за 10 лет всего по 10 событий на каждый день, займут 36500 строк в таблице Excel

но можно и не импортивать данные а просто прилинковать таблицы Excel и нумеровать сроки уже в запросе основанном на такой прилинкованной таблице - при этом порядок сортировки (последовательность записей) будет всегда остваться той, что задана в файле Excel.

на примере приведенных выше данных - допустим вам нужно присвоить порядковый номер событиям перечисленным в таблице Excel. Последовательно +1 в пределах каждого одного дня, со сбросом счетчика каждый новый день


 COUNTER |   DATE   |   PLACE   |   RATE
---------+----------+-----------+----------
  1      | 12/09/06 |   1       |   1.00
  2      | 12/09/06 |   0       |   1.07
  3      | 12/09/06 |   3       |   1.88
  1      | 17/09/06 |   0       |   1.00
  2      | 17/09/06 |   2       |   1.13
  1      | 18/09/06 |   1       |   1.43
  1      | 19/09/06 |   4       |   1.99
  2      | 19/09/06 |   1       |   1.75
  3      | 19/09/06 |   0       |   1.08
  4      | 19/09/06 |   2       |   1.03
  5      | 19/09/06 |   3       |   1.56
  1      | 20/09/06 |   1       |   1.98
  2      | 20/09/06 |   0       |   1.77


если просто экспортировать данные в Access, то при пересортировке таблицы может нарушиться последовательность событий и, например, расчеты основанные на данных предыдущих приодов окажутся выполненными некорректно.

если предварительно подготавливать данные в таблице Excel - можно легко ошибиться - неверно указать номер, пропустить дату и не сбросить счетчик номера в "1"

Но если просто прилинковать таблицу Excel и используя ее в качестве источника строк, выполнить нехитрый запрос, вида (пример):

SELECT 
LINKED.DATE, numerate([DATE]) AS COUNTER, LINKED.PLACE, LINLKED.RATE
FROM LINKED
WHERE (((LINKED.DATE) IS NOT NULL) AND ((firstnum())=TRUE))
ORDER BY LINKED.DATE, COUNTER;


обращающийся к PUBLIC функциям нумерации, вынесенными в отдельный модуль basNumerate
в декларациях модуля должны быть объявлены переменные:


Option Compare Database
Option Explicit

Private curNum As Long - текущее значение счетчика
Private curDate As Date - текущее значение даты


функция numerate (получает в качестве аргумента значение даты текущей записи из запроса):


Public Function numerate (DATE As Date) As Long

If curDate <> DATE Then 'проверяем равна ли дата предыдущей
    curNum = 1 ' если нет начинаем считать COUNTER с "1" - т.е. новый или первый день
Else
    curNum = curNum + 1 ' если дата равна предшествующей (тот же день) увеличиваем счетчик на "1"
End If

    COUNTER = curNum - записываем значение счетчика
    curDate = ActionDate - запоминаем значение даты
  
End Function

функция firstnum (вспомогательная функция в условии WHERE нужна для того, чтобы зайти в каждую запись - не возвращает данных в запрос)


Public Function firstnum() As Boolean
    firstnum = True
End Function


пронумеровав таким образом записи в запросе для расчетов,

можно будет применять все инструменты Access, в том числе агрегатные функции (SUM, AVG) и агрегатные функции домена (DLOOKUP, DMIN), обращаясь к записи по ее идентификатору (COUNTER & DATE дадут уникальный идентификатор записи)

если не использовать проверку на дату и не переустанавливать счетчик в "1" то такого рода запрос пронумерует все записи подряд - в той последовательности как они идут в таблице Excel.

работает достаточно быстро


Ваше имя:

Пароль:

Цитировать: [quote][/quote] Код: [code][/code]
Жирный: [b][/b] Наклонный: [i][/i]
URL: [url][/url] 

Сообщение:

 Размер файла не более 50 Кбт. Большие файлы можно размещать на www.slil.ru

Прикрепить:

 

Для вставки смайлов в текст щелкните по значку.