יצירת מסנן לדו"ח באקסס עם תנאים
-
יש לי דו"ח באקסס שמכיל נתונים עם (בין היתר) השדות הבאים:
מדינה = טקסט
סוכן מטפל = טקסט מתוך רשימה
מאושר - תיבת סימון
סיים טיפול = תיבת סימוןואני רוצה שבלחיצה על "צור דוח" ייבדוק עם האובייקטים (כל אחד בנפרד)
filter_co, agent, set_ok, done
מכילים נתונים או ריקים, או במקרה של ב' האחרונים אם תיבת הסימון לא מוגדרת (עם ריבוע, לא וי ולא ריק).
ואם filter_co מכיל נתונים ייצור מסנן לדו"ח שייפתח רק עם הרשומות שהנתון של השדה Country שווים לנתון שמכיל filter_co.
וכן לתיבת הרשימה המשולבת של agent.
ואם תיבת הסימון set_ok מסומנת בוי או באיקס יוסיף למסנן גם סינון של השדה Approval_status וכן לאוביקט done.ולאחמ"כ ייפתח את הדו"ח.
וזאת שאלתי לאלופי האקסס דכאן האם או כיצד ניתן לעשות זאת באמצעות vba? רק אדגיש שאני רוצה לדעת איך לעשות את זה, לכן אם אי מי יביא את הקוד כתוב אשמח שגם יבאר מה מו מי.
נ.ב. אני מעוניין גם לעשות שיהיה אפשר ליצור דו"ח עבור כלל הסוכנים יחד ע"י שהשרשור של ערך התנאי של agent יהיה בלולאה על עמודת שמות הסוכנים בטבלת הסוכנים, ובמרה הזה במקום לפתוח את הדו"ח בתצוגת הדפסה ייצא את הדו" לPDF אל תיקיית משנה בתיקיית קובץ האקסס האם גם זה אפשרי?
-
@hp079 אפשר.
הואיל ואתה רוצה להבין את התהליך, אתן לך את הכיוון, ומשם תוכל להמשיך לבד.
בתחביר פתיחה של דוח, ניתן להגדיר מסנן או תנאי:OpenReport ReportName, View, FilterName, WhereCondition, WindowMode, OpenArgs
מה שצריך זה לבנות בקוד את התנאי באופן דינאמי כמחרוזת, ואז לפתוח את הדוח עם התנאי.
לדוגמא:Dim DynamicCondition As String DynamicCondition="" ' Add first condition If (Not IsNull(chkSet_ok)) Then DynamicCondition="Ok=" & CStr(chkSet_ok) End If ' Add second condition: If (Not IsNull(chkDone)) Then DynamicCondition=IIF(Len(DynamicCondition)>0, DynamicCondition & " AND ", "") & "Done=" & CStr(chkDone) End If ' Add more conditions If (Only_Bar_Mitsva) Then DynamicCondition=IIF(Len(DynamicCondition)>0, DynamicCondition & " AND ", "") & "Age>=13" End If ... ' Open report with all my conditions: DoCmd.OpenReport "MyReport", acViewNormal, WhereCondition:=DynamicCondition
-
@hp079 לתיבת סימון תלת מצבית שלושה ערכים אפשריים:
True, False, Null
. הערךNull
משמעותו ללא סימון.
אם אין סימון בתיבה זו, מסתמא הלוגיקה היא לא לסנן לפיה, לכן בשורה:If (Not IsNull(chkSet_ok)) Then
אתה מוודא שהתיבה מסומנת, כלומר אם היא לא מכילה
Null
, ואם כן, השורה:DynamicCondition="Ok=" & CStr(chkSet_ok)
מוסיפה לתנאי את הבדיקה האם השדה Ok (בדוח) שווה לערך טבלת הסימון.
לא צירפתי דוגמא לבדיקה של תיבות הטקסט, אבל היא אמורה להתבצע באופן כמעט זהה, דהיינו אם ישנו ערך כלשהו בתיבת הטקסט, אז להוסיף תנאי סינון לשדה הרצוי לפי ערך זה.
הנה דוגמא שמסננת את הדוח כך שיוצגו רק רשומות בהן ערך השדה FirstName מכיל את מחרוזת החיפוש שהוקלדה בתיבת הטקסט txtSearchFirstName:If (Len(txtSearchFirstName) > 0) Then DynamicCondition=IIF(Len(DynamicCondition)>0, " AND ", "") & "FirstName LIKE %" & txtSearchFirstName & "%" End If
-
@OdedDvir עשיתי כך
Dim DynamicCondition As String DynamicCondition = "" ' Add first condition If (Not IsNull(Set_ok)) Then DynamicCondition = "ok=" & CStr(Set_ok) End If If (Not IsNull(done)) Then DynamicCondition = "done=" & CStr(done) End If If (Len(agent) > 0) Then DynamicCondition = IIf(Len(DynamicCondition) > 0, " AND ", "") & "agent LIKE %" & "agent" & "%" End If ' Open report with all my conditions: DoCmd.OpenReport "logForOne", acViewPreview, WhereCondition:=DynamicCondition
אבל התנאי של תיבת הטקסט "agent" על השדה agent נתקע, כשעשיתי את התיבות סימון לבד, זה עבד יופי.
-
@hp079 כתב ביצירת מסנן לדו"ח באקסס עם תנאים:
DynamicCondition = IIf(Len(DynamicCondition) > 0, " AND ", "") & "agent LIKE %" & "agent" & "%"
יש לך גרשיים מיותרות מסביב למשתנה
agent
. אתה צריך לרשום כך:DynamicCondition = IIf(Len(DynamicCondition) > 0, " AND ", "") & "agent LIKE %" & agent & "%"
כשה-
agent
האחרון בשורה מתייחס לשם של פקד תיבת הטקסט בטופס המכיל את שם הסוכן לחיפוש. -
@hp079 מתוך ההערה שלך, הערת את תשומת לבי שהייתה לי טעות בקוד המקורי שלי: בכל תנאי חדש אני דרסתי את התוכן הקודם של
DynamicCondition
במקום לשרשר אליו תנאי נוסף...כתשובת המשקל, עכשיו אני אחיל קצת עקרונות תכנות, ואכתוב את הכל מחדש כך:
Dim DynamicCondition As String Private Sub AddCondition(ByRef currentCondition As String, conditionToAdd As String) Begin If (Len(currentCondition)=0) Then currentCondition = conditionToAdd Else currentCondition = currentCondition & " AND " & conditionToAdd End If End DynamicCondition="" ' Add first condition If (Not IsNull(chkSet_ok)) Then AddCondition DynamicCondition, "Ok=" & CStr(chkSet_ok) ' Add second condition: If (Not IsNull(chkDone)) Then AddCondition DynamicCondition, "Done=" & CStr(chkDone) ' Add more conditions If (Only_Bar_Mitsva) Then AddCondition DynamicCondition, "Age>=13" ... ' Open report with all my conditions: DoCmd.OpenReport "MyReport", acViewNormal, WhereCondition:=DynamicCondition
-
@OdedDvir גירסה שלי:
Dim DynamicCondition As New Collection If Not IsNull(chkSet_ok) Then DynamicCondition.Add "Ok=" & CStr(chkSet_ok) If Not IsNull(chkDone) Then DynamicCondition.Add "Done=" & CStr(chkDone) If Only_Bar_Mitsva Then DynamicCondition.Add "Age>=13" DoCmd.OpenReport "MyReport", acViewNormal, WhereCondition:=JoinCollection(DynamicCondition, "AND")
JoinCollection:
Function JoinCollection(col As Collection, operator As String) Dim result As String For i = 1 To col.Count - 1 result = result & col(i) & operator Next result = result & col(i) JoinCollection = result End Function
-
@hp079 אם תצרף את נוסח השגיאה אוכל להתייחס.
הגרסא של @dovid יותר תיקנית, רק שבטעות נעלם ממנו ריפוד הרווחים מסביב לאופרטור, וצ"ל כך:result = result & col(i) & " " & operator & " "
אפשר גם לבודד כל תנאי על ידי סוגריים, כדי למנוע בעיות קדימות במקרים מסויימים:
result = result & "(" col(i) & ") " & operator & " " Next result = result & "(" col(i) & ")"
-
@hp079 לפי הדוגמא שלך זה הקוד שאתה צריך
Private Sub פקודה16_Click() Dim DynamicCondition As New Collection If Not IsNull(ts_active) Then DynamicCondition.Add "פעיל=" & ts_active If Not IsNull(ts_conected) Then DynamicCondition.Add "מחובר=" & ts_active If Len(txt_sug) > 0 Then DynamicCondition.Add "סוג='" & CStr(txt_sug) & "'" If Len(txt_name) > 0 Then DynamicCondition.Add "שם='" & CStr(txt_name) & "'" DoCmd.OpenReport "דוח1", acViewPreview, WhereCondition:=JoinCollection(DynamicCondition, " AND ") End Sub Function JoinCollection(col As Collection, operator As String) Dim result As String For i = 1 To col.Count If i <> 1 Then result = result & operator & " " result = result & "(" & col(i) & ") " Next JoinCollection = result End Function