PDA

View Full Version : سوال: محاسبه زمان حضور در شرکت (دستگاه کارت ساعت)



AAtoZZ
یک شنبه 12 دی 1389, 19:10 عصر
از اساتید یه سوالی داشتم
من به یک دستگاه کارت ساعت متصل شدم و داده های رو ازش می خوانم و داخل یک table وارد میکنم. (در SQL2005)


DateTime


CardID


No


2011-01-01 7:30:00 AM


82013265


168











2011-01-01 3:00:00 PM


82013265


215











2011-01-01 4:00:00 PM


82013265


230











2011-01-01 7:30:00 PM


82013265


270













طبیعتا در ابتدای هر روز اولین رکورد هر CardID مربوط به ورود می باشد؛ ممکن است یک شخص در روز چندین بار از شرکت خارج و وارد شود.

چطور میشه مدت زمان حضور هر شخص در شرکت رو محاسبه کرد؟




ممنون که وقتی که صرف می کنید

حمیدرضاصادقیان
دوشنبه 13 دی 1389, 07:49 صبح
سلام.
شما ابتدا با یک Select تمام رکوردهایی که مثلا بایک ID در روز ثبت شده پیدا میکنید. و زمانها رو براساس نوع Type اونها از هم کم میکنید.
جدول شما باید یک فیلد Type داشته باشه که مشخص کنه این رکورد خروجی هست یا ورودی.
براساس اون میشه این کارو انجام داد.
اگر ساختار جدول رو کامل قرار بدید میشه کوئری اونو نوشت.

AAtoZZ
دوشنبه 13 دی 1389, 18:24 عصر
جدول چندین فیلد داره که این ها درگیر این Querry خواهند بود


-No-|--CardID---|---------DateTime----------
168 | 82013265 | 2011-01-01 7:30:00 AM
……|………………|…………………… ………………
215 | 82013265 | 2011-01-01 3:00:00 PM
……|………………|…………………… ………………
230 | 82013265 | 2011-01-01 4:00:00 PM
……|………………|…………………… ………………
270 | 82013265 | 2011-01-01 7:30:00 PM
……|………………|…………………… ………………

در نمایش ورود خروج های یک روز و نمایش تعداد ورود خروج های هر شخص در هر روز مشکلی ندارم.
وقتی شمارش میشه وقتی تعداد زوج باشه یعنی شخص خارج شرکته و اگر فرد باشه یعنی داخل شرکته.


ممنون از وقتی که صرف میکنید.

حمیدرضاصادقیان
سه شنبه 14 دی 1389, 07:48 صبح
وقتی شمارش میشه وقتی تعداد زوج باشه یعنی شخص خارج شرکته و اگر فرد باشه یعنی داخل شرکته.

ایتجا یک تناقض پیش میاد. فرض کنید کاربر اول صبح میاد یادش میره کارت بزنه. وقتی میره بیرون کارت خروج میزنه و ساعت ورود رو در برگه ساعت کار نوشته و از مدیر امضا میگیره.
اینجا چطوری محاسبه میشه.در اینجا کاربر از شرکت خارج شده ولی طبق محاسبات شما کاربر در شرکت هست.

AAtoZZ
سه شنبه 14 دی 1389, 16:46 عصر
ایتجا یک تناقض پیش میاد. فرض کنید کاربر اول صبح میاد یادش میره کارت بزنه. وقتی میره بیرون کارت خروج میزنه و ساعت ورود رو در برگه ساعت کار نوشته و از مدیر امضا میگیره.
اینجا چطوری محاسبه میشه.در اینجا کاربر از شرکت خارج شده ولی طبق محاسبات شما کاربر در شرکت هست.
اطلاعاتی دستی وارد یک Table دیگه میشن و زمان محاسبات اعمال میکنم.
اگر با فرض اینکه همه، همیشه کارت بزنن سوال حل بشه و مدت زمان حضور اشخاص مشخص بشه، تلفیق داده های دستی با داده های ساعت زن کار سختی نخواهد بود. (چون غیر از اینکه کارت یادشون بده حالت های دیگه هم هست که باید در نظر گرفته بشه. ولی فعلا سوال من در مورد همین یک Table است)

iman_Delphi
سه شنبه 14 دی 1389, 17:22 عصر
سلام

ایتجا یک تناقض پیش میاد. فرض کنید کاربر اول صبح میاد یادش میره کارت بزنه. وقتی میره بیرون کارت خروج میزنه و ساعت ورود رو در برگه ساعت کار نوشته و از مدیر امضا میگیره.

دوست عزیز برای محاسبه دو راه در شرکت ها وجود دارد 1) گیت ورود و خروج را جدا در نظر میگیرند که مشکلی که آقای صادقیان فرمودن پیش نیاد
2) اگر گیت رو یکی در نظر بگیرن محدودیت زمانی برای زدن کارت در نظر میگیرن (مثلا تا ساعت 9 کارت بزنن و از اون ساعت به بعد باید به ارشدشون اطلاع بدن که ساعتشون رو ثبت کنه در سیستم)
این به منظور قطع برق و سرویس ندادن و غیره قابل انعتافتره
وگرنه مجبوری محاسبات اتمیکت رو ادامه بدی آخرشم میبینی باگ داره

iman_Delphi
سه شنبه 14 دی 1389, 17:23 عصر
یکی دیگه هم که یادم اومد اینه که شما باید اجازه ندی در محدوده زمانی مثلا" 1 دقیقه به تعداد دفعات کارت بزنن

AAtoZZ
چهارشنبه 15 دی 1389, 09:04 صبح
سلام

دوست عزیز برای محاسبه دو راه در شرکت ها وجود دارد 1) گیت ورود و خروج را جدا در نظر میگیرند که مشکلی که آقای صادقیان فرمودن پیش نیاد
2) اگر گیت رو یکی در نظر بگیرن محدودیت زمانی برای زدن کارت در نظر میگیرن (مثلا تا ساعت 9 کارت بزنن و از اون ساعت به بعد باید به ارشدشون اطلاع بدن که ساعتشون رو ثبت کنه در سیستم)
این به منظور قطع برق و سرویس ندادن و غیره قابل انعتافتره
وگرنه مجبوری محاسبات اتمیکت رو ادامه بدی آخرشم میبینی باگ داره
در شرکت ما امکان اعمال این نوع محدودیت ها وجود نداره، کارمند ها ممکنه هر ساعتی بیان و برن، یک ورودی و یک دستگاه بیشتر هم نداریم.


یکی دیگه هم که یادم اومد اینه که شما باید اجازه ندی در محدوده زمانی مثلا" 1 دقیقه به تعداد دفعات کارت بزنن
کارت زدن در یک دقیقه فقط یکبار در دستگاه ثبت میشه و دفعات بعدی در اون دقیقه اثر نداره.


ممنون میشم اگر کسی بتونه کمک کنه.

tooraj_azizi_1035
چهارشنبه 15 دی 1389, 13:05 عصر
سلام،
دوستان من این کد رو تو Access تست کردم:

SELECT Sum([Table2]![enterdate]-[Table2]![exitdate]) AS Expr1
FROM Table1 INNER JOIN Table2 ON Table1.ID = Table2.ID;


تفریق ساعت خروج از ورود را در SQL Server نمی دانم همین چیزی که نوشته ام می شود یا نه.

Table1 کارمندان و Table2 اطلاعات رفت و آمد را نگهداری می کند. این کد جمع کل ساعات را محاسبه می کند. اگر فقط ردیف های فرد را جمع کنیم حاصل جمع کل حضور در شرکت می شود.
یعنی به قسمت انتخاب فیلدها این کد اضافه شود:
ROW_NUMBER() OVER(ORDER BY BY Table1.ID AS RowNum
و در قسمت WHERE این کد را بنویسیم:
WHERE RowNum/2<>0
دوستان من SQL Server جلوم نیست این کدها رو تست کنید.

AAtoZZ
چهارشنبه 15 دی 1389, 16:40 عصر
سلام،
دوستان من این کد رو تو Access تست کردم:

SELECT Sum([Table2]![enterdate]-[Table2]![exitdate]) AS Expr1
FROM Table1 INNER JOIN Table2 ON Table1.ID = Table2.ID;
تفریق ساعت خروج از ورود را در SQL Server نمی دانم همین چیزی که نوشته ام می شود یا نه.

Table1 کارمندان و Table2 اطلاعات رفت و آمد را نگهداری می کند. این کد جمع کل ساعات را محاسبه می کند. اگر فقط ردیف های فرد را جمع کنیم حاصل جمع کل حضور در شرکت می شود.
یعنی به قسمت انتخاب فیلدها این کد اضافه شود:
ROW_NUMBER() OVER(ORDER BY BY Table1.ID AS RowNum
و در قسمت WHERE این کد را بنویسیم:
WHERE RowNum/2<>0
دوستان من SQL Server جلوم نیست این کدها رو تست کنید.

مشکل اینجاست فیلدی به نام exitdate یا enterdate وجود نداره!
یک فیلد Date وجود داره که یک در میان ورود و خروج رو ثبت کرده.

iman_Delphi
چهارشنبه 15 دی 1389, 17:05 عصر
خب اگه مشکلت اینه که کارمنداتون ورود و خروج دارند بیایین یک ستون فلگ اضافه کنین و یک ستون row که هر بار کارت میزنن یک بار صفر بزنه یک بار هم یک بزنه

و اگر کارمندی یادش رفته بود کارت بزنه رکوردش رو دستی وارد کنین و از اون رکورد به بعد رو دوباره فلگ هاشون رو به حالت اصلی برگردونه تا ورود ها از خروج ها متمایز بشن اما دقت کنید که این روش استاندارد نیست و افزونگی داره

کاربرد ستون row هم اینه که به ترتیب ورود و خروج ها رو مشاهده کنید دوست عزیز

احتمالا" به یک تریگر نیاز داری و یک کرسر

AAtoZZ
چهارشنبه 15 دی 1389, 19:34 عصر
خب اگه مشکلت اینه که کارمنداتون ورود و خروج دارند بیایین یک ستون فلگ اضافه کنین و یک ستون row که هر بار کارت میزنن یک بار صفر بزنه یک بار هم یک بزنه

و اگر کارمندی یادش رفته بود کارت بزنه رکوردش رو دستی وارد کنین و از اون رکورد به بعد رو دوباره فلگ هاشون رو به حالت اصلی برگردونه تا ورود ها از خروج ها متمایز بشن اما دقت کنید که این روش استاندارد نیست و افزونگی داره

کاربرد ستون row هم اینه که به ترتیب ورود و خروج ها رو مشاهده کنید دوست عزیز

احتمالا" به یک تریگر نیاز داری و یک کرسر
یعنی به نظر شما هم تنها راهش استفاده از cursor هست؟
اینطوری کار مشکل و سرعت پایین خواهد آمد.

ممنون میشم دوستان برای نوشتن این کرسر راهمایی کنند.

masoudcg1
جمعه 17 دی 1389, 21:37 عصر
سلام علیکم
با استفاده از کرسر ها میتوانید محاسبه انجام دهید
به این ترتیب که ابتدا رکورد های مربوط به آن شخص را درون یک کرسر قرار دهید و دو به دو پیمایش کنید و مقادیر تاریخ ها را از هم کم کنید و مقدار را در یک متغییر نگه دارید
و برای رکورد های بعدی مقدار متغییر را با رکورد های جدید جمع کنید
الا آخر
اگر مایلید من پروسیجرش را بنویسم
یا حق

AAtoZZ
شنبه 18 دی 1389, 11:41 صبح
بالاخره یک راه حل بدون استفاده از کرسر با سرعت بالا یافت شد!
اگر با این کد هر دو کارت زدن پشت سر هم رو یک شماره بدیم، مراحل بعدی خیلی ساده است

select *,(ROW_NUMBER()over (partition by cardid order by ID)+1)/2 as i
from CardEvents
WHERE Date > @DateStart AND
Date < DATEADD(DAY,1,@DateEnd)) d
group by i,cardid

هوراااااااااااااااااااااا ااااااااااا