سلام
اگر بخواهيم تاريخ ها رو به صورت شمسي در ديتا بيس ذخيره كنم . نوع فيلد رو نميشه Date گذاشت چون مثلا در مورد ماه دوم ميلادي ، تعداد روزها 28 تاست و لي شمسي 31 ، پس نميشه برخي مقادير رو وارد كرد.
پس فكر ميكنم مجبوريم فيلدها رو بصورت String تعريف كنيم.
اما مشكل اين روش در موقع جستجو بين داده ها مطرح ميشه. يعني در مورد فورمت Date ميشه براحتي مقايسه صورت بگيره . ولي در مورد فرومت String (حتي با وجود اينكه به شكل تاريخ مثلا اينجوري: 1383/11/13 وارد بشن) نميشه به خوبي مقايسه رو انجام داد.
حالا پيشنهاد شما چيه؟ آيا سال و ماه و روز رو از رشته String جدا كنيم و تك تك اونها رو مقايسه كنيم ؟! يا راه ديگه اي وجود داره ؟
ممنون
نبي
قربان هم ولايتي خودم برم
ببين اين جز اولين موارديه كه تو يه پروژه بخصوص ديتا بيس خيلي وقت آدم رو ميگيره
و حسابي اذيتت ميكنه من يه پروژه داشتم كه تمام كارهاي حسابداريش با استفاده از مقايسه تاريخ ها بود
و جز همون مجموعه هست كه خدمتتون عرض كردم
مشكل رو دقيقا شما پيدا كردين
مشكل فقط ذخيره نيست تابع DATEDIFFتابع فوق العلده مهميه و به راحتي هم نميشه نوشتش
چون اگه بخواي 29 يك ماه رو با 2 ماه بعد مقايسه كني دردسر ميشه يعني يه كم كار ميبره
اينم چندتا از راه حل هاش:
ميتونيم يه فيلد تو ديتا بيس برا ذخيره تاريخ ميلادي از نوع ديت بزاريم و يه فيلد هم از نوع تكست برا تاريخ شمسي
ميلادي رو از طريق date برميگردنيم و تو جدول سيو ميكنيم
شمسي رو هم كه برا تبديلش تابع زياد هست(من يكي تو سايت گذاشتم كه البت نياز به يه كم تغيير داره)
و بوسيله اون تو يه فيلد تكست ميريزيم
البته در اين حالت بهتره اول اون رو با تابع format قالب بندي كنيم تا همه يه جور ذخيره شن و بعد به مشكل نخوريم
حالا براي مقايسه كردن تاريخ ها datediff رو روي تابع ميلادي پياده ميكنيم ولي به كاربر فيلد معادل شمسي رو نشون ميديم
همچنين ميتونيم روز ماه و سال رو بطور مجزا تو سه فيلد مختلف ذخيره كنيم و برا مقايسش يه الگوريتم ساده كافيه
بحث بعدي هم مرتب سازي تاريخ هاست بسته به اينكه از كدوم روش بالا استفاده كرديم
اگه اولي رو پياده كرديم به شرط اينكه يه فرمت ثابت برا ذخيره داشته باشيم خيلي راحت با تابع mid
رشته اي استخراج ميكنيم كه فقط از اعداد اون تاريخ تشكيل شده و بعد با يه دستور اسكيوال يه كم توردتو و لي ساده
ركورد ها رو براساس اون اعداد مرتب ميكنيم كه خيلي هم باحال كار ميكنه
فقط دقت كن تو دستور اسكيوال اينكار رو بصورت ضمني انجام ميديم و ديگه نياز نيست برا اعداد استخراجي هم يه فيلد بزاريم
اگه از روش دومي استفاده كرديم باز اول روز بعد ماه بعد سال رو مقايسه ميكنيم . بعد تركيب و انداختن تو يه دستور اسكيوال
قربان شما عليرضا
سلام
از توضيحات خوب و كاملت ممنونم كلي استفاده كردم .
در مورد ايجاد دوتا فيلد ميلادي و شمسي در ديتا بيس روش خوبيه ولي من نيازي نميبينم . چون اگر دو تا فيلد معادل هم باشن پس وجود هر دو همزمان نميتونه كاري بكنه وميشه مبنا رو همون شمسي يا ميلادي قرار داد و بعد از مقايسه و استخراج نهايتا تاريخ ها رو به ميلادي يا شمسي كه مد نظره برگردونيم (يعني ديگه نيازي نيست كه از فيلد كناريش كه مربوط به مثلا تاريخ شمسي معادله استفاده كرد!) (نميدونم در اين مورد تونستم منظورم رو برسونم يا نه..)
من خودم نظرم اينه كه تاريخ ها رو بصورت رشته اي و شمسي در ديتا بيس ذخيره كنيم . و براي مقايسه اونها يه تابع مقايسه اي براي سالهاي شمسي بنويسيم بطوري كه اول سال و ماه و روز رو با mid از رشته استخراج كنه و سال بعد ماه بعد روز رو مقايسه كنه و بفهمه كدوم يكي بزرگتر و كدوم كوچيكتره . و در نتيجه ميشه فهميد كدوم تاريخ در محدوده مجازه و اون رو چاپ كنيم .
البته شايد هم منظورت از توضيحاتي كه دادي همين باشه نهايتا ...!
بازم ممنون
نبي
ببين نبي جون اينكه براش يه فيلد جداگونه بزاري يا نه دقيقا بستگي به نوع پروژت داره
درمواردي مثلا اگه بخواي سريع يه ليست از تاريخ ها و درآمدها مثلا نشون بدي
خوب كافيه ديتا گريد رو به اون فيلد وصل كني و كار خيلي راحت و سريع ميشه
ولي اگه ميخواهي پشت صحنه فقط يه محاسبه منفرد ساده انجام بدي خوب آره اتفاقا داشتن يه فيلد اضافي تازه افزونگي تو ديتا بيست ايجاد ميكنه و كاملا هم مخالف قواعد نرمال سازي پايگاه دادست
همون جور كه عرض كردم بسته به نيازت بايد تصميم بگيري كه از كدوم روش استفاده كني
قربانت
موفق باشي
متاسفانه تاريخ توي ديتا بيس چون فارسي نيست و تاريخ ايراني رو پشتيباني نميكنه معضل بزرگي هست . بنظر من بايد يه مبدل خوب تاريخ به فارسي نوشته بشه و ازش استفاده بشه.
بازم از توضيحات آرن و اشكان ممنونم .
يه فانكشن براي اينكه كدوم تاريخ بزرگتره نوشتم اينشكلي:
کد:
Function MoghayeseShamsi(dat1 As String, dat2 As String) As String
'NabiKAZ2001_se@yahoo.com
'Date (YYY/MM/DD)
For i = 1 To Len(dat1)
ch = Mid(dat1, i, 1)
If ch = "/" Then n = n + 1
Select Case n
Case 0: If ch <> "/" Then sal1 = sal1 & ch
Case 1: If ch <> "/" Then mah1 = mah1 & ch
Case 2: If ch <> "/" Then roz1 = roz1 & ch
End Select
Next i
n = 0
For i = 1 To Len(dat2)
ch = Mid(dat2, i, 1)
If ch = "/" Then n = n + 1
Select Case n
Case 0: If ch <> "/" Then sal2 = sal2 & ch
Case 1: If ch <> "/" Then mah2 = mah2 & ch
Case 2: If ch <> "/" Then roz2 = roz2 & ch
End Select
Next i
sal1 = Val(sal1)
sal2 = Val(sal2)
mah1 = Val(mah1)
mah2 = Val(mah2)
roz1 = Val(roz1)
roz2 = Val(roz2)
If sal1 > sal2 Then
MoghayeseShamsi = ">": Exit Function
ElseIf sal1 < sal2 Then
MoghayeseShamsi = "<": Exit Function
Else
If mah1 > mah2 Then
MoghayeseShamsi = ">": Exit Function
ElseIf mah1 < mah2 Then
MoghayeseShamsi = "<": Exit Function
Else
If roz1 > roz2 Then
MoghayeseShamsi = ">": Exit Function
ElseIf roz1 < roz2 Then
MoghayeseShamsi = "<": Exit Function
Else
MoghayeseShamsi = "=": Exit Function
End If
End If
End If
End Function
سادست ولي شايد بدرد دوستان بخوره .
ممنون
نبي
خيلي راحت شما ديتاي تاريخ به شكل زير زخيره كنيد
13830101
هر مقايسه اي روي اين فيلد كه نوع اون از استرينگ جواب مي ده
مشكلي بود ميل بديد جواب مي دم
mahdi_hanifnjad@yahoo.com
mh نوشته است:خيلي راحت شما ديتاي تاريخ به شكل زير زخيره كنيد
13830101
هر مقايسه اي روي اين فيلد كه نوع اون از استرينگ جواب مي ده
مشكلي بود ميل بديد جواب مي دم
mahdi_hanifnjad@yahoo.com
اينم حرفيه :wink:
فك كنم روش خوبي باشه
ازت ممنونم دوست عزيز
نبي
روش كه خيلي جالبه فكر كنم براي جمع و تفريق كردن تاريخ ها هم براي اينكه مشكلي پيش نياد ميشه از روشي كه تو اسمبلي براي جمع كدهاي بي سي دي با دستورات هگز استفاده مي كردي بشه استفاده كرد
همون DAA يا DAََ
ha_60 نوشته است:روش كه خيلي جالبه فكر كنم براي جمع و تفريق كردن تاريخ ها هم براي اينكه مشكلي پيش نياد ميشه از روشي كه تو اسمبلي براي جمع كدهاي بي سي دي با دستورات هگز استفاده مي كردي بشه استفاده كرد
همون DAA يا DAََ
منظورت اينه كه مثلا تو مبناي 60 جمع و تفريق رو انجام بديم !؟
مبناي 60 ؟؟؟؟؟
فرض كن 1380/7/10 رو داشته باشيم و تاريخ 40 روز ديگه رو به خواهيم ميشه 13800710+40=13800750 چون دو رقم اول از 30 بيشتر بايد 70 رو به جمع اضافه كنيم (مشكل 31 روز رو هم يه جوري مي شه حل كرد)پس ميشه 13800820 (1380/8/20) حالا اگه دو رقم دوم بيشتر از 12 بود بايد 8800 رو اضافه كني