Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.11.14;
Скачать: CL | DM;

Вниз

Учет времени   Найти похожие ветки 

 
Pashkerton   (2004-10-13 13:11) [0]

Добрый день.
На SQL Server-e есть следующая таблица:
| cardcode | action | date | time |
где: cardcode - код сотрудника
    action - событие (0-сотрудник ушел, 1-сотрудник пришел)
    date - дата событи action
    time - время события action
За один день сотрудник может несколько раз прийти на работу и уйти. Число приходов и уходов должно быть одинаковым. Отсюда вопрос - каким алгоритмом организовать поиск "коллизий", если человек допустим лишний раз отметился, или вообще забыл отментится.


 
Ega23 ©   (2004-10-13 13:12) [1]

Гы-ы-ы... Знаем-знаем...
В какой конторе работаешь, конкурент?


 
Pashkerton   (2004-10-13 13:15) [2]

Скажем так, за полярным кругом...


 
Ega23 ©   (2004-10-13 13:24) [3]

Мурманск? Билибино?


 
Pashkerton   (2004-10-13 13:26) [4]

Гораздо проще. Апатиты.


 
Ega23 ©   (2004-10-13 13:30) [5]

А не Полярные Зори, случайно?   :о)


 
jack128 ©   (2004-10-13 13:34) [6]

Количество приходов = select count(*) from table where action = 1 and cardcode = :cardcode and date = :date
Количество уходов = select count(*) from table where action = 0 and cardcode = :cardcode and date = :date
и сравнивай.

Если бы уход кодировался -1 , то можно было бы проще
select sum(action) from cardcode = :cardcode and date = :date  Если не равно нулю, то коллизия.


 
Johnmen ©   (2004-10-13 13:55) [7]

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

Это понятно.

>или вообще забыл отментится.

А это прикольно... Чел на работе, а следов в таблице об этом нет.
:)


 
Ega23 ©   (2004-10-13 14:08) [8]

2 jack128 ©   (13.10.04 13:34) [6]
Ага, а если он заполночь засиделся? Или в ночную смену работает?
Поверь там далеко не всё просто.


 
Pashkerton   (2004-10-13 14:17) [9]

Ха - ха - ха ))
Да собственно не так уж там всё и сложно. Я сейчас в розысках новых решений. Работающая программа есть, тока она на VBA. Я перешел на SQL 2000. Теперь делаю всё красиво.


 
jack128 ©   (2004-10-13 14:23) [10]

Ega23 ©   (13.10.04 14:08) [8]
Тогда вы сначала дайте определение, что такое РАБОЧИЙ ДЕНЬ  ;-)


 
Pashkerton   (2004-10-13 14:26) [11]


> Johnmen

На сервере висит сервис. на клиентских машинах маленькое приложение следующего характера: при логоне на сервис отправляется запрос, отметился ли человек. При отрицательном ответе его периодически начинают раздражать MessageBox-ы гласящие о том что он не отметился.


 
Pashkerton   (2004-10-13 14:35) [12]

Да сколько бы он не просидел, хоть даже заполночь. В Delphi замечательно работает следующее:
TimeToStr(StrToDateTime("13.10.2004 23:30:39") - StrToDateTime("14.10.2004 00:10:29"));


 
Johnmen ©   (2004-10-13 14:38) [13]

>jack128 ©   (13.10.04 14:23) [10]

День здесь непринципиален.
Просто решение, которое ты привел, неверно, т.к. сотрудник может отметиться два раза подряд при входе и два раза при выходе. Это коллизия. Даже две. А ты не ловишь...:)


 
Ega23 ©   (2004-10-13 14:40) [14]

TimeToStr(StrToDateTime("13.10.2004 23:30:39") - StrToDateTime("14.10.2004 00:10:29"));

А нафига так сложно????? И, кстати, нафига в таблице 2 разных поля date и time? Можно же одним datetime обойтись...


 
Reindeer Moss Eater ©   (2004-10-13 14:43) [15]

А что вообще мы хотим узнать написав какой-то запрос?
На работе ли человек или уже дома?
Цель-то какая?

Число приходов и уходов должно быть одинаковым.

А типа без SQL сервера человек запутается и дважды уйдет с работы, придя на нее всего один раз.

Какая цель?


 
Pashkerton   (2004-10-13 14:43) [16]

Так вот я и ищу решение отлова коллизий. А исправлять их ручками
, и только после производить подсчет времени. Интелектуальные алгоритмы (чтоб сами исправляли коллизии) я писать не собираюсь.


 
Reindeer Moss Eater ©   (2004-10-13 14:44) [17]

Если хотим узнать сколько времени чел был на работе, то надо при регистрации "выхода" искать последний вход и считать время.
Расчитав его, складывать в таблицу - табель.
Вот и все.


 
Pashkerton   (2004-10-13 14:51) [18]


> Reindeer Moss Eater

Утром пришел - отметился. 8.00
Пошел на обед - отметился - 13,00
Пришел сытый -не отметился - ~ 14.00
Поше домой - отметился - 17,00

А вообще я таких кадров насмотрелся. По секрету, есть такие сотрудники которым карточки вообще в руки давать не следует )


 
Reindeer Moss Eater ©   (2004-10-13 14:56) [19]

Я что-то полета мысли понять не могу.

Ставим систему. (Что бы иметь некие данные)
После чего зачем-то пытаемся найти софтварное подтверждение такой естественной особенности человека - "один раз пришел - один раз ушел (а не два)"
Потом ищем ошибки.
Потом их правим руками.
Потом на основе данных введенных руками делаем выводы о рабочем времени человека.

По моему сама система учета времени в этой изящной архитектуре - вещь лишняя.


 
Johnmen ©   (2004-10-13 14:58) [20]

>Pashkerton

Уточни. Тебе надо считать "рабочее" время или искать коллизии ?


 
Pashkerton   (2004-10-13 15:07) [21]

Сначала найти и уничтожить коллизии, а потом подсчитать время.


 
Reindeer Moss Eater ©   (2004-10-13 15:08) [22]

Искать коллизии :

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


 
Reindeer Moss Eater ©   (2004-10-13 15:09) [23]

Сначала найти и уничтожить коллизии, а потом подсчитать время.

И как же посчитать время, если сытый чел пришел  с обеда на час позже чем надо и забыл шоркнуть карточкой?

Для детского сада такая система учета времени.


 
jack128 ©   (2004-10-13 15:19) [24]

Johnmen ©   (13.10.04 14:38) [13]
в рамках существующей структуры таблицы это возможно ? ;-)


 
Reindeer Moss Eater ©   (2004-10-13 15:27) [25]

Конечно возможно


 
Johnmen ©   (2004-10-13 15:27) [26]

>jack128 ©   (13.10.04 15:19) [24]

Конечно.

>Pashkerton  

Коллизии примерно так (при условии, что две соседние отметки не могут иметь одинаковое datetime):
SELECT * FROM Table T1
JOIN Table T2 ON (T1.cardcode=T2.cardcode) AND
 (T1.datetime<T2.datetime) AND (T1.action =T2.action) AND
 (T2.datetime-T1.datetime=(SELECT MIN(T3.datetime-T1.datetime)
             FROM Table T3
             WHERE (T3.cardcode=T1.cardcode) AND
               (T3.datetime>T1.datetime))


 
Pashkerton   (2004-10-13 15:28) [27]

Спорить ни с кем не собираюсь. Как можно судить о чем то (в рамках существующей структуры...) по одной таблице. Предложил на рассмотрение вопрос в поисках интересных решений. Вывел на рассмотрение только те поля таблицы, которые вписывались imho в суть вопроса.


 
Reindeer Moss Eater ©   (2004-10-13 15:30) [28]

Я тебе не про таблицу и её структуру (Вполне корректную кстати).
А про систему учета рабочего времени.


 
Reindeer Moss Eater ©   (2004-10-13 15:32) [29]

Коллизии такого рода можно обнаружить если чел забыл отметить приход или уход.
Если же он забудет и то и другое подряд, то коллизий не будет.
Зато будет фигня в табеле.


 
jack128 ©   (2004-10-13 15:37) [30]

Johnmen ©   (13.10.04 15:27) [26]
Коллизии примерно так (при условии, что две соседние отметки не могут иметь одинаковое datetime):
нету у нас datetime. У нас только DATE
Pashkerton   (13.10.04 13:11)
date - дата событи action


 
Johnmen ©   (2004-10-13 15:39) [31]

>jack128 ©   (13.10.04 15:37) [30]

Ну зачем придираться. Это общая схема. Ничто не мешает подправить под раздельное хранение. Но я Пашкертону уже говорил, что такое разделение не только неудобно, но и вредно...
:)


 
Pashkerton   (2004-10-13 15:40) [32]

Система вполне эффективна для малых предприятий (у нас 52 человека). В помещении находится 2 терминала которые считывают штрихкоды с карточек (проходной нет, они просто висят на стеночке и глаза не мазолят). На сервере стоит SQL Server с работает сервис который постоянно опрашивает терминалы. В любой момент я могу узнать кто находится в помещении (если он не забыл отметится). Благодаря ей у человека получается "свободный" график, "чем больше работаешь - тем больше плучишь".


 
Reindeer Moss Eater ©   (2004-10-13 15:43) [33]

нету у нас datetime. У нас только DATE
Date тоже можно выкинуть.
И использовать числовой первичный ключ.

Система вполне эффективна для малых предприятий
Система вполне эффективна, если можно доверять её данным.
Если же их надо править руками, то это игра в систему.


 
Pashkerton   (2004-10-13 15:46) [34]

Да я же кусочек таблицы выдал на рассмотрение (и об этом я писал чуть выше). Вот "полная версия":
|rkey|cardcode|date|time|tdatetime|terminalid|action|time_stamp|
rkey - это ясно
cardcode - код карты
date - дата
time - время
tdatetime - оно самое про что Вы писали
terminalid - идентификатор терминала с которого получена запись
action - событие
time_stamp - тут всё ясно


 
jack128 ©   (2004-10-13 15:49) [35]

Johnmen ©   (13.10.04 15:39) [31]
Не придираюсь я.. Я так... ;-)


 
Ega23 ©   (2004-10-13 16:00) [36]

2 Pashkerton   (13.10.04 15:46) [34]
date - дата
time - время
и
time_stamp - тут всё ясно

IMHO, для данной таблицы лишнее.
Вот наша структура аналогичной таблицы:
unid        
PersId      
datin                                                  
PointUID
ZoneFromUID
ZoneToUID
CardId      
Pincode    
CardNr      
actFl
TraceTypCod



Страницы: 1 вся ветка

Текущий архив: 2004.11.14;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.052 c
1-1099393717
Pentium133
2004-11-02 14:08
2004.11.14
Не вызывается Change! Что делать?


9-1088325591
ASoft
2004-06-27 12:39
2004.11.14
DelphiX


14-1098986853
Луарвик
2004-10-28 22:07
2004.11.14
"Хрендопрешь" - игра!


1-1098899254
Павел
2004-10-27 21:47
2004.11.14
Общий доступ к файлам


1-1099047852
Pentium133
2004-10-29 15:04
2004.11.14
TStringList и IniFile