PDA

View Full Version : سوال: شمارش داده های تکراری



navid4731
پنج شنبه 31 فروردین 1402, 23:16 عصر
سلام
چطور میشه یه ستون به جدول اضافه کرد که داده های تکراری به ترتیب شماره گذاری بشن ، یعنی بزنه که این چندمین باره که این داده داره تو‌ جدول تکرار میشه ، منظورم dcount نیست مثلا یه داده وسط جدول رو‌ بزنه این ۳۴ امین باره که این داده تکرار میشه بعدیش رو بزنه ۳۵ امین بار و‌ الی اخر

mazoolagh
یک شنبه 03 اردیبهشت 1402, 16:03 عصر
روش حل این دقیقا مشابه با پرسش قبلی است:
https://barnamenevis.org/showthread.php?573904-%D8%A7%D9%81%D8%B2%D9%88%D8%AF%D9%86-%D8%AF%D8%A7%D8%AF%D9%87-%D8%AC%D8%AF%D8%A7%DA%AF%D8%A7%D9%86%D9%87-%D8%A8%D9%87-%D9%87%D8%B1-%D9%81%DB%8C%D9%84%D8%AF-%D8%AF%D8%B1-%D9%81%D8%B1%D9%85-%D8%A7%DA%A9%D8%B3%D8%B3

باید یک حلقه بسازین و در رکوردست فرم بگردین.
کدش ساده است ولی چند مورد هست که باید دقت کنین:

1- فیلدی که قراره تعداد تکرار اون شمرده بشه رو ایندکس کنین.
2- از رخداد after update برای تشخیص وضعیت استفاده کنین.
3- چون الزاما همیشه رکورد جدید نیست و ممکنه مقدار فیلد رو در رکوردهای قبلی تغییر بدین،
لازم هست که در رخداد before update مقدار قبلی رو هم نگه دارین
و در after update عملیات شمارش رو برای هر دو مقدار جدید و قدیم(در صورت نیاز) انجام بدین.
4- در هنگام جستجو، بجای اینکه مستقیما از رکوردست فرم استفاده کنین، یک clone ازش بگیرین و عملیات رو در اون انجام بدین (جستجو و محاسبات).
5- در پایان کار فرم رو refresh کنین.
6- برای جستجو در رکوردست از findfirst/findnext استفاده کنین و حلقه رو تا زمانی که nomatch نشده ادامه بدین.
7- یک شمارنده با مقدار اولیه 0 بسازین و به ازای هر find یکی بهش اضافه کنین و مقدارش رو فیلد نتیجه شمارش بریزین.
8- اگر مثل پرسش قبلی قرارهست بجای شمارش یک حرف از a و به بعد به انتهای مقدار فیلد بچسبونین،
کافی هست از همین شمارنده برای محاسبه حرف استفاده کنین : chrw(ascw("a")+counter)

navid4731
دوشنبه 04 اردیبهشت 1402, 15:09 عصر
سلام
ممنونم از پاسخدهی دقیق و با حوصلتون
اگر امکانش هست اینو تو یه فایل اکسس بصورت مثال بهم نشون بدین خیلی ممنونتون میشم

mazoolagh
پنج شنبه 07 اردیبهشت 1402, 18:54 عصر
با فرض این که:
1- اسم فیلد مورد نظر برای شمارش X باشه،
2- اسم فیلدی که قراره شمارش X رو نگه داره Nth باشه،
3- اسم فیلدی که قراره شمارش X رو بصورت استرینگی با افزودن a,b,... به آخر X نگه داره Xaz باشه:

اول از همه؛ در ماجول فرم یک متغیر برای نگهداری مقدار قبل از ویرایش X تعریف میکنیم(مورد 3 پست شماره 2):
PRIVATE old_X AS VARIANT
و در رخداد مربوطه مقداردهی میکنیم برای استفاده بعدی:
SUB X_BEFOREUPDATE
old_X=X.OLDVALUE
END SUB

mazoolagh
پنج شنبه 07 اردیبهشت 1402, 19:13 عصر
برای سادگی کار، فرض میکنیم از پیش یک روتین برای شمارش نوشتیم به اسم Calc_For که مقدار رو از ما میگیره و در رکوردست فرم دنبالش میگیره و ...
در رخداد afterupdate:
SUB X_AFTERUPDATE()
DIRTY=FALSE
Calc_For(X)
Calc_For(old_X)
REFRESH
END SUB

که منطق ساده ای داره:
اول با dirty=false رکورد فعلی رو save میکنیم و یک بار برای X شمارش میکنیم.
یک بار هم برای old_X شمارش انجام میدیم.

اگر رکورد جدید باشه، مقدار old_X برابر null هست و مشکلی در محاسبات پیش نمیاد،
ولی این قابلیت رو میده که مقادیر null رو هم میتونیم بشمریم.

mazoolagh
پنج شنبه 07 اردیبهشت 1402, 19:25 عصر
حالا میریم سروقت روتین Calc_For :
SUB CALC_FOR(X_VALUE AS VARIANT)
DIM counter AS LONG ' =0
DIM whr AS STRING


IF ISNULL(X_VALUE) THEN
whr="ISNULL(X)"
ELSE
whr="X=" & X_VALUE
END IF


WITH RECORDSETCLONE
.MOVEFIRST
.FINDFIRST whr
DO UNTIL .NOMATCH
counter=counter + 1
.EDIT
!NTH=counter
!XAZ=NZ(!X , "(NULL)") & CHRW(ASCW("A")-1 + counter)
.UPDATE
.FINDNEXT whr
LOOP
.CLOSE
END WITH
END SUB

این هم منطق ساده ای داره:
- اول شمارنده رو تعریف میکنیم : counter ،
- یک استرینگ whr برای ساخت شرط جستجو ،
- در recordsetclone فرم (نه رکوردست فرم!) از ابتدای اون (movefirst) شروع میکنیم
و دنبال اولین مورد میگردیم (findfirst)
- یک حلقه داریم که تا زمانی که نتیجه جدیدی پیدا نشه (nomatch) دنبال نتایج میگرده
- با هر موردی که پیدا میشه به شمارنده یکی اضافه میکنیم و در Nth میریزیم
همچنین در Xaz هم یک کپی از X که به آخرش یک حرف (از a و به بعد) چسبیده میریزیم

navid4731
یک شنبه 10 اردیبهشت 1402, 23:01 عصر
خیلی خیلی خیلی ممنونم از پاسخگوییتون🙏🏻🙏🏻🙏🏻🙏 🏻یچیزیو متوجه نشدم x_value از کجا مقداردهی میشه؟

mazoolagh
شنبه 16 اردیبهشت 1402, 08:42 صبح
خیلی خیلی خیلی ممنونم از پاسخگوییتون��������� ���������������� ���������������� �����یچیزیو متوجه نشدم x_value از کجا مقداردهی میشه؟

مقدارش رو از همون پارامتری میگیره که بهش پاس میشه!
با اجرای
Calc_For(X) در واقع مقدار X رو به روتین پاس میکنین.