דילוג לתוכן
  • דף הבית
  • קטגוריות
  • פוסטים אחרונים
  • משתמשים
  • חיפוש
  • חוקי הפורום
כיווץ
תחומים

תחומים - פורום חרדי מקצועי

💡 רוצה לזכור קריאת שמע בזמן? לחץ כאן!
  1. דף הבית
  2. תוכנה
  3. אקסס למתחילים: יצירת מערכת לניהול תורמים

אקסס למתחילים: יצירת מערכת לניהול תורמים

מתוזמן נעוץ נעול הועבר תוכנה
25 פוסטים 2 כותבים 12.1k צפיות
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • OdedDvirO מנותק
    OdedDvirO מנותק
    OdedDvir
    כתב ב נערך לאחרונה על ידי OdedDvir
    #21

    פרק כ: הפקת קבלות: חלק א: אפיון, קשר של יחיד ליחיד ועוד קצת VBA

    אני רוצה להוסיף למערכת שלנו יכולת הפקה של קבלות לתורמים.
    אני מעוניין באפיון הבא:

    1. לכל תרומה תהיה רק קבלה אחת ויחידה.
    2. לקבלות יהיה מספר רץ ייחודי.
    3. לקבלה יהיה תאריך הנפקה.
    4. אפשרות להוספת הודעת טקסט אישית על הקבלה.

    לכאורה, הפתרון הפשוט הוא להוסיף עוד כמה שדות לטבלת התרומות:
    ReceiptNumber
    ReceiptDate
    ReceiptMessage
    ולמלא אותם בכל פעם שיוצרים קבלה.
    למה לטבלת התרומות?
    כי כל קבלה שייכת רק לתרומה אחת בלבד.

    אבל אם נחשוב על כך, לפתרון זה ישנם שני חסרונות גדולים:

    1. אני צריך לנהל בעצמי את המספר הרץ. וזה לא כל כך טריוויאלי. בכל הנפקת קבלה חדשה אצטרך לסרוק את כל טבלת התרומות, למצוא את הערך המקסימלי, להוסיף 1 ולהקצות אותו לקבלה החדשה. זה מסורבל.
      במקרה שיש כמה משתמשים במערכת, זה אפילו מסוכן, כי יתכן ושניהם ינפיקו בו זמנית את אותו המספר לשתי קבלות שונות...
    2. גם ניהול תאריך הנפקת הקבלה יהיה רק באחריותי, ולא על ידי המערכת, כי לא אוכל להקצות ערך ברירת מחדל לשדה, שהרי אם כן, הוא ייקבע ברגע שאצור תרומה חדשה, ומסתמא תאריך הנפקת הקבלה לא תמיד זהה לתאריך התשלום. בנוסף אני עלול לשכוח למלא את הנתון, מה שיגרום לי סיבוך מיותר עם מס הכנסה...

    אבל אל דאגה, יש פתרון יעיל בהרבה.

    נכון שלכאורה פרטי הקבלה שייכים באופן הגיוני לתרומה, אך בעצם, תרומות וקבלות הן שתי ישויות נפרדות, וראויות להיות נפרדות גם בנתונים.

    אנחנו נפריד בין נתוני התרומות לבין נתוני הקבלות, וניצור ביניהן יחס של אחד לאחד.

    יחס של אחד לאחד קובע כי לכל רשומה בטבלה א תיתכן אך ורק רשומה אחת קשורה בטבלה ב.

    ניתן להמשיל זאת לפריסת הטבלה על ידי סכין לשתי טבלאות נפרדות: אחת לתרומות ואחת לקבלות.

    באופן עקרוני תכנון טוב של בסיס נתונים רלציונאלי מושתת על הפרדה של ישויות בנתונים. להפרדת ישויות על ידי יחס אחד לאחד יש כמה יתרונות:

    • צמצום בנעילת רשומות
      כאשר משתמש עובד על רשומה מסויימת, אותה רשומה ננעלת עבור שאר המשתמשים. בהפרדת הנתונים לשתי טבלאות אנו מאפשרים עבודה על שתי הטבלאות במקביל ללא חשש.
    • חיסכון בשטח אחסון
      לעתים אנו לא מעוניינים בשמירת כל הנתונים עבור כל הרשומות, אלא רק עבור חלקן.
      הפרדת הנתונים תאפשר לנו לשמור את הנתונים רק עבור הרשומות שבחרנו.
      במקרה שלנו זה לא רצוי, כי אנחנו כן רוצים ליצור קבלה עבור כל תרומה (יש כאן מישהו ממס הכנסה?) אבל ייתכנו מקרים אחרים שבהם זה שייך.
    • הקטנה בצריכת משאבים
      הרבה מבסיסי הנתונים משתמשים במנגנון מטמון Cache עבור אחסון זמני של נתונים. גם בבחירת חלק מהעמודות (למשל על ידי שאילתת בחירה), לרוב ה-DB מייבא את כל השורה למטמון. הפרדת נתונים תקטין את המשאבים הנדרשים עבור כך.
      במקרה שלנו זה ממש לא קריטי, אבל תארו לעצמכם טבלה עם 200 או 300 עמודות (וכן, יש דברים כאלו), מסתמא המערכת נדרשת רק לחלק מהעמודות ברוב הקריאות ל-DB.
    • יצירת טריגרים מבוססי טבלה מדוייקים יותר (מחוץ לתחום הדרכה זו)

    חשוב לציין כי להפרדת נתונים על ידי יחס אחד לאחד יש גם חסרונות, בעיקר אם תמיד נצטרך לייבא את שתי הטבלאות על ידי JOIN. במקרה כזה עדיף למקם את כל הנתונים בטבלה אחת.

    אז בואו נראה כיצד עושים זאת:

    ניצור טבלה חדשה עבור הקבלות, עם השדות הבאים:
    DonationID – מפתח ראשי, מסוג מספר שלם ארוך. ערך ברירת מחדל Null
    ReceiptNumber – מספור אוטומטי
    ReceiptDate – תאריך\שעה. ערך ברירת מחדל =Now()
    ReceiptMessage – מסוג טקסט קצר.
    6517c132-6821-4756-baa3-c8b1e7f0f0fc-תמונה.png
    נשמור את הטבלה בשם Receipt.

    שימו לב כי בשיטת עיצוב זו פתרנו בקלילות את שתי הבעיות שהעלנו לעיל: ניהול מספר רץ עבור הקבלה, וניהול תאריך ההנפקה, והעברנו את האחריות על כך למערכת בלבד. בכך חסכנו לעצמנו כאב ראש ושגיאות.

    הגדרת יחסי הגומלין
    נפתח את עורך יחסי הגומלין, ונייבא את טבלת הקבלות.
    כעת נגרור את שדה ID מטבלת Donation אל השדה DonationID בטבלת הקבלות, ונבחר בחלון עריכת קשרי הגומלין: "אכוף שלמות הקשרים בין הטבלאות".
    שימו לב שאקסס יצרה יחס של אחד לאחד בין הטבלאות:
    28516ece-fdd1-4a16-993f-a19f79fd4f35-תמונה.png

    מהיכן היא יודעת לעשות זאת?
    אקסס מזהה כי יצרנו קשר גומלין בין שני שדות מפתח. מציאות זו תיתכן רק בקשר של אחד לאחד.
    סיגרו את החלון ושימרו את השינויים.

    יצירת טופס להקלדת נתוני קבלה
    כעת ניצור את הטופס עבור הקבלות, שוב באופן אוטומטי: נבחר את טבלת התרומות, ומהתפריט למעלה: יצירה > טופס. נעבור לתצוגת עיצוב ונערוך בטופס זה כמה שינויים: נסיר את שדה המפתח, ונשנה את גודל הכותרת, תיבות הטקסט ונקטין גם את הטופס:
    dba3c21d-6102-44a7-b289-fd4abbd0a69a-תמונה.png

    כעת נבחר את תיבת הטקסט של ההודעה לתורם, ובמאפיינים תחת הלשונית "אחר" נשנה את המאפיין "התנהגות מקש Enter" ל: שורה חדשה בשדה:
    f00a247d-1b80-483f-b1f8-e1b807005a34-תמונה.png

    ברירת המחדל של מקש Enter בטופס היא מעבר לשדה הבא, אולם בהודעה האישית לתורם, ייתכן ונרצה להכניס ירידות שורה. הגדרה זו קובעת כי אם נרצה להוסיף ירידת שורה בהודעה האישית, נוכל לעשות זאת על ידי מקש אנטר, ואקסס תכניס תו ירידת שורה בשדה, במקום לעבור לשדה הבא.

    נסגור ונשמור את הטופס בשם: frmReceipt.
    כעת נוסיף את הטופס כטופס משנה לטופס כרטיס התרומה: frmDonationCard, על ידי פתיחת הטופס של כרטיס התרומה וגרירת הטופס החדש לשם:
    535fee73-f1c9-47a7-b5bd-89b6c4945b29-תמונה.png

    במאפיינים של פקד טופס המשנה, נעבור ללשונית "נתונים", ונשים לב כי אקסס קבעה את הקשר בין הטפסים לפי הקשר שיצרנו:
    30490118-8106-4d06-963b-bee167e68e00-תמונה.png

    נעבור ללשונית "תבנית", ונגדיר את המאפיין עוגן אופקי ל-ימין, כדי שטופס המשנה יוצג בצד הנכון של טופס האב:
    505ed615-b499-4bfd-91ad-198c4f2e0620-תמונה.png

    נסגור את טופס האב ונשמור את השינויים. לאחר מכן נפתח אותו שוב, ונכניס את ההודעה אישית עבור התרומה הראשונה:
    c60d6098-61ac-4157-b009-e87c83a3fab0-תמונה.png

    שימו לב שאקסס הקצתה את מספר הקבלה ואת תאריך ההנפקה באופן אוטומטי:
    4af8d4e2-1525-4d04-aa44-bd770928569e-תמונה.png

    סגרו את הטופס ופתחו את טבלת הקבלות, שימו לב שאקסס גם קבעה נכון את שדה המפתח, כך שיתאים לתרומה:
    528ca3fd-76af-4d5e-8f6f-b8b04db3d791-תמונה.png

    בדק בית
    המערכת עובדת די טוב, אך יש עוד כמה שיפורים לבצע:

    1. אין אפשרות ליצור קבלה מבלי להכניס ערך כלשהו. ומה אם איננו מעוניינים להוסיף טקסט אישי לקבלה?
      את בעיה זו נשאיר לכם לפתור בשיעורי הבית.

    2. בטופס המשנה, לא אמורה להיות יותר מקבלה אחת עבור כל תרומה, ולכן לחצני הניווט שם מיותרים. אם ננסה להכניס יותר מקבלה אחת עבור תרומה מסויימת, נקבל שגיאה.

    בואו נראה:
    פתחו שוב את טופס כרטיס התרומה, ובטופס המשנה של הקבלה, לחצו על לחצן הרשומה החדשה, והכניסו טקסט כלשהו בהודעה:
    5327c247-335d-4c5a-92e9-b2f2ae418c12-תמונה.png

    נסו לסגור את הטופס. אקסס לא תאפשר לשמור את הרשומה, ותציג הודעת שגיאה:
    0460c47d-facb-42de-bc90-ea770d78daf0-תמונה.png
    לחצו על אישור.
    אקסס תציג את השאלה הבאה:
    7725e3dd-c567-4179-885b-367453543b1f-תמונה.png

    בחרו כן.

    כתוצאה מהמהלך הזה, הנתונים שהכנסתם יאבדו. גם המספר הרץ של הקבלות יקפוץ על המספר 2, והקבלה הבאה תקבל את המספר 3, כי המספר 2 כבר "שרוף" במחיקת הרשומה השגויה.

    פתרון לבעיה
    כדי להימנע מלהיכנס בכלל למצב שכזה, נבצע כמה שינויים.
    אנו מעוניינים לחסום אפשרות להוספת קבלה לתרומה שיש לה קבלה קיימת. לשם כך נשתמש במאפיין "אפשר תוספות" או באנגלית "AllowAdditions" של הטופס. כאשר מאפיין זה מכיל ערך True, ניתן להוסיף רשומות. וכאשר הוא מכיל את הערך False, אין אפשרות להוסיף רשומות.

    כיון שהרשות להוספת קבלה לתרומה נקבעת על ידי התרומה הנוכחית (אנו רוצים לאפשר זאת רק אם אין לה כבר קבלה), נשתמש בפונקציית VBA שנצמיד לארוע של התרומה הנוכחית בטופס האב.
    פתחו את טופס האב frmDonationCard בתצוגת עיצוב, וצרו פונקציה עבור הארוע "בנוכחי":
    837413b9-defd-4dbb-aadf-017a8ff2852d-תמונה.png
    הקלידו את הקוד הבא:

    Private Sub Form_Current()
        If Me.frmReceipt.Form.Recordset.RecordCount = 0 Then
            Me.frmReceipt.Form.AllowAdditions = True
        Else
            Me.frmReceipt.Form.AllowAdditions = False
        End If
    End Sub
    

    הקוד הנ"ל בודק את מספר הרשומות בקבוצת הרשומות של טופס המשנה (שורה 2), ואם הוא שווה 0 (=אין קבלה), אז קובע את ערך המאפיין AllowAdditions בטופס המשנה ל-True, וכך מאפשר הוספת רשומה חדשה (שורה 3), אחרת, הוא קובע את המאפיין ל False, ובכך חוסם את האפשרות (שורה 5).
    סגרו ושמרו.

    עדיין יש כאן פתח לשגיאות, כי כאשר ניצור תרומה חדשה, המאפיין AllowEditions בטופס המשנה יהיה על True, ונוכל להכניס עוד תרומה. עלינו לדאוג להעבירו למצב False לאחר ההוספה. לשם כך נשתמש בפונקציה נוספת שנצמיד כמובן לארוע "לאחר הוספה" של טופס המשנה.
    פתחו את טופס המשנה frmReceipt בתצוגת עיצוב, וצרו פונקציה עבור הארוע "לאחר הוספה":
    80faab41-7cf0-4485-bb55-c14070e57c4f-תמונה.png

    הקלידו את הקוד הבא:

    Private Sub Form_AfterInsert()
        Me.AllowAdditions = False
    End Sub
    

    חיזרו לטופס על ידי הקשה על Alt+F11, עיברו ללשונית תבנית, והסירו את לחצני הניווט מהטופס, הם מיותרים כעת:
    f2fdd3bf-dbc6-4d61-bc96-bdc8a2bd4940-תמונה.png

    תוספת: הכינוי Me
    כדי לגשת לטופס הפתוח אנו משתמשים במילה השמורה Me. המילה Me היא כינוי למופע של מחלקת הטופס שהפעיל את האירוע.

    מה הפשט?

    הטופס הוא בעצם סוג של תבנית. הוא דוגמא שממנה אנו יכולים ליצור כמה מופעים של אותו הטופס, בדיוק כמו תבנית צורה של עוגיה, שממנה ניתן ליצור כמה עוגיות זהות.

    לדוגמא, במערכת ההפעלה ניתן לפתוח במקביל כמה מסמכים של וורד, בכל פתיחה של מסמך חדש, מערכת ההפעלה יוצרת מופע חדש של תוכנת וורד.

    בשפת תכנות, לתבנית קוראים בשם מחלקה (או מודל). ולצורות שיוצרים ממנה קוראים מופעים.

    כל מופע מכיל את כל הפונקציונאליות והמאפיינים של המחלקה שממנה נוצר.

    אם נחשוב על כך, כל טופס יכול באופן עקרוני להיות פתוח בו זמנית כמה וכמה פעמים.
    נתאר לעצמנו מצב דמיוני שבו הטופס פתוח ב-10 מופעים. כאשר נסגור מופע אחד, אותו מופע יפעיל את הארוע "סגירת טופס", אפילו שתשעת המופעים האחרים פתוחים. כיצד נדע מתוך הקוד, איזה מופע של הטופס נסגר?

    לשם כך שפת VBA מספקת לנו את המאפיין Me ככינוי שבאמצעותו ניגשים ישירות למופע הפעיל של הטופס שהריץ את הקוד.
    או אם תרצו: אם אין אני לי – Me לי.

    שיעורי בית:
    כדי להתחמק מן הבעיה הראשונה שהזכרנו לעיל, נכריח את המשתמש להכניס נתון כלשהו בקבלה: אמצעי השליחה.

    1. צרו טבלה חדשה בשם DeliveryMethod שתכיל שדה מזהה ID ושדה נוסף בשם Description.
      טבלה זו תכיל את אפשרויות השליחה של הקבלה, כאשר 1 מציין שהקבלה תישלח בדואר רגיל, ו-2 מציין כי הקבלה תישלח בדואר אלקטרוני.

    2. הוסיפו שדה נוסף לטבלת הקבלות בשם DeliveryMethodID מטיפוס מספר ארוך. הערכים לשדה זה יילקחו מהטבלה בסעיף א, על ידי תיבה משולבת. קבעו את ערך ברירת המחדל של השדה ל-Null.

    3. בטבלת הקבלות, הפכו את כל השדות לנדרשים, למעט השדה של ההודעה האישית.

    4. הוסיפו פקד תיבה משולבת עבור השדה הנ"ל בטופס הקבלה.

    תגובה 1 תגובה אחרונה
    14
    • OdedDvirO מנותק
      OdedDvirO מנותק
      OdedDvir
      כתב ב נערך לאחרונה על ידי OdedDvir
      #22

      פרק כא: הפקת קבלות: חלק ב: עיקרון ה-DRY, מחולל הדוחות

      כדי שנוכל להדפיס את הקבלות שיצרנו, אנו צריכים ליצור דוח.
      באופן עקרוני, דוח באקסס מאוד דומה לטופס:

      • הוא יכול להיות מאוגד לטבלה, או לא מאוגד
      • הוא יכול להכיל את רוב הפקדים שיכולים להימצא בטופס
      • יש לו מגוון של ארועים שניתן להצמיד אליהם קוד VBA
      • הוא יכול להכיל דוחות משנה

      היתרון הגדול ביצירת דוח הוא היכולת להציג נתונים בצורה נוחה להדפסה.

      אז בואו וניצור את הדוח הראשון שלנו: דוח עבור קבלות לתורמים.
      נחשוב:
      אילו נתונים צריכים להופיע על הקבלה?
      מסתמא נרצה את כל הנתונים שבטבלת הקבלות, אך חסרים שם הרבה פרטים, כמו סכום ותאריך התרומה, ושם התורם והכתובת שלו.

      למעשה, אין לנו שדה כתובת בטבלת התורמים עדיין, אז בואו ניצור אחד כזה:
      a91c5f1b-9053-4b90-8698-21db248f6593-תמונה.png
      כדי להציג את כל פרטי הקבלה, ניצור שאילתת צירוף.

      שלב א: יצירת שאילתת צירוף להצגת פרטי הקבלה
      ניצור שאילתה חדשה, ונוסיף את שלושת הטבלאות: קבלות, תרומות, ותורמים, למשטח העבודה, אקסס תזהה את הצירוף בין הטבלאות לפי מה שהגדרנו ביחסי הגומלין:
      0cf6a774-a7f4-4b28-8fff-53b314485730-תמונה.png
      נבחר להציג את השדות הבאים:
      a8a10fbc-525b-4be9-8212-ac4b70a8df47-תמונה.png

      הממ... עדיין חסר לי את שדה שם התורם.

      אני יכול להציג את שם המשפחה ואת השם הפרטי בנפרד, אבל אני רוצה כמובן להציג את שם התורם המלא.

      לא בעיה!
      אני יכול ליצור שדה מחושב FullName שמחבר את השם הפרטי ושם המשפחה של התורם.

      אבל רגע, זה נשמע לי מוכר...
      יש לי כבר שאילתה שעושה זאת: qryDonor_FullName.

      במקום ליצור שוב שדה מחושב, בואו ונשתמש בה.
      למה?

      עיקרון ה-DRY
      לפני כעשרים שנה, פירסמו שני מתכנתים אמריקאים את העיקרון הבא בתכנון מערכות:
      Don't Repeat Yourself (אל תחזור על עצמך) או בקיצור DRY. הנוסח הרשמי לעיקרון זה הוא:
      לכל פיסת ידע צריך להיות ייצוג יחיד, חד משמעי וסמכותי במערכת.
      במילים פשוטות, זה אומר שלא נשכפל שום חלק במערכת אלא אם כן הדבר הכרחי.

      עקרון זה נועד כדי להפחית כפילויות מיוצרות במערכת, ועל ידי כך ליצור מערכת קלה לתחזוקה, כי שינוי של גורם יחיד במערכת לא יאלץ שינויים נוספים בגורמים אחרים שאינם קשורים אליו לוגית.
      ניקח לדוגמא את המקרה שלנו:
      כרגע, שם התורם המלא מוצג לפי הסדר הבא: שם משפחה + רווח + שם התורם. נניח שבעוד שנה ירצה בעל הבית להציג את שמות התורמים המלאים בסדר הפוך, דהיינו במקום כהן אברהם – אברהם כהן וכו'.
      אם הרכבת השם המלא של התורם מבוצעת רק במקום יחיד במערכת, דהיינו בשאילתה הנ"ל, כל שעלינו לעשות הוא לשנות את הגדרת השדה המחושב שם – והשינוי ישתקף בכל מקום במערכת.
      אבל, אם בכל פעם יצרנו שוב את השדה המחושב מחדש – זה הופך לעבודת נמלים מייגעת...

      אז יופי, בואו ונוסיף גם את השאילתה למשטח העבודה, והופ – נראה שהפעם אקסס לא הייתה כל כך מבריקה, והחליטה לצרף את השדה ID מטבלת התרומות לשדה ID בשאילתה, כפי שמוצג בדרמטיות בתמונה הבאה:
      4a48265f-906b-432f-9a04-e757c837fc0b-תמונה.png

      מדוע זה קרה?
      אקסס זיהתה את שם השדה ID הזהה בשתי מקורות הנתונים, והחליטה "לעזור לנו" על ידי יצירת הצירוף עבורנו. אבל זה כמובן לא נכון!

      אם היינו קוראים לשדה המפתח בכל טבלה בשם מלא, כפי שנהגנו במפתח הזר, למשל DonationID במקום ID בטבלת התרומות, או DonorID במקום ID בטבלת התורמים וכו', המנגנון של אקסס אכן היה עוזר לנו.
      זו אכן סכמה נפוצה, ובאמת בתחילת דרכי כך נהגתי, אבל היא פחות מקובלת, ובקוד היא נעשית מסורבלת עוד יותר, כי ניגשים לשדה המזהה כך: Donor.DonorID במקום כך: Donor.ID.
      לכן אני מעדיף לוותר על העזרה של אקסס כאן, וליצור ידנית את הצירוף, תמורת הרווח של קוד ושאילתות יותר קריאים.

      בואו נתקן את הצירוף:
      נבחר את החץ ונמחק אותו על ידי הקשה על מקש Delete, ובמקום, נגרור את שדה ID מטבלת התורמים לשדה ID בשאילתת השם המלא, כך:
      c3be820d-041e-469e-818a-34c9fdd5be67-תמונה.png

      כעת נוסיף גם את השדה FullName לחגיגה:
      9594ee29-b8b9-4bb6-96de-c424a4dcef01-תמונה.png

      נעבור לתצוגת גליון נתונים כדי לראות שהכל תקין. על הדרך, בואו נוסיף עוד הודעות אישיות לתרומות של כהן אברהם:
      585505e0-d51e-4203-b1a9-25cea5f2c7c9-תמונה.png

      נשמור את השאילתה בשם: qryReceipt_Details (=פרטי קבלה)
      כעת ניתן סוף סוף לעבור לשלב יצירת הדוח.

      שלב ב: יצירת דוח עבור הקבלה
      בחרו מתפריט היצירה > עיצוב דוח:
      c281a687-0226-449e-9e4c-9543bd8db122-תמונה.png

      אקסס תייצר עבורנו דוח ריק. שימו לב שהדוח מחולק לשלושה אזורים:

      • כותרת עליונה בעמוד: חלק זה יודפס בראש כל עמוד חדש.
      • פירוט: החלק העיקרי של הדוח.
      • כותרת תחתונה בעמוד: חלק זה יודפס כמובן בתחתית כל עמוד.

      ישנם עוד חלקים נוספים שאפשר לערוך בדוח, כפי שנראה אי"ה בהמשך.

      כדי שהטופס יציג לנו את נתוני הקבלות, צריך לאגד אותו לשאילתה שיצרנו. לשם כך נבחר בפקד הדוח, על ידי לחיצה על הפינה השמאלית העליונה (בדומה לפקד טופס, זהו הפקד שנבחר אוטומטית בתצוגת עיצוב):
      51fac50f-e2ff-4ce2-be4e-bde4ce621892-תמונה.png

      כעת נלחץ על מקש F4 כדי להציג את חלונית המאפיינים, ניגש לכרטיסית הנתונים, ובמאפיין מקור רשומה נבחר את שאילתת פרטי הקבלות qryReceipt_Details:
      6cedb319-f280-4065-b8a2-e8be0977af09-תמונה.png

      נבחר מהתפריט למעלה את האפשרות: הוסף שדות קיימים כדי להציג את השדות שנמצאים בטבלה:
      1866ee58-2c3b-4401-91c1-564f44af4073-תמונה.png

      נבחר את כל השדות ונגרור אותם לתוך חלק הפירוט של הטופס:
      3d1fb473-fb2c-41a7-b4ef-9d1f63bf2fa3-תמונה.png

      נעצב את הדוח כיד הדמיון הטובה עלינו:
      b9e91abe-30d6-4b12-959b-8b101d2b5992-תמונה.png

      כשסיימנו, נבחר מתפריט העיצוב את התצוגה: הצג לפני הדפסה:
      83289bba-93cb-4b4f-9626-932534fdf7f2-תמונה.png

      כדי לראות את התוצאה:
      6cefd1e6-57e7-4ac0-b29a-780fbd07b2f6-תמונה.png
      שימו לב כי בתצוגה זו מוצגת בכל עמוד קבלה אחת בלבד. כדי לעבור לעמוד הבא, נשתמש בסרגל הניווט למטה:
      d427ad31-ad50-457d-98d5-4c9caa1decb8-תמונה.png

      נשמור את הדוח בשם: rptReciept_Details.

      זהו לבינתיים, מקווה שנהנתם!

      בפרק הבא אי"ה נלמד על טפסים רציפים.

      אני משאיר כמה שיעורי בית, בעיקר בעיצוב (מהקל למאתגר):

      1. הסירו את המסגרות מסביב לתיבות הטקסט בדוח.
      2. הוסיפו בכותרת התחתונה של העמוד את הכיתוב: "הודפס על ידי מערכת לניהול תורמים גירסא 0.01"
      3. הוסיפו את שעת ההדפסה המדוייקת בכותרת העליונה.
      4. הצמידו את ראשי התיבות נ"י לשם התורם כך שיופיעו מיד לאחריו בצורה יפה בלי רווח גדול.
      5. הסירו את השעה מתאריך החשבונית ומתאריך התרומה.

      בהצלחה!

      תגובה 1 תגובה אחרונה
      9
      • OdedDvirO מנותק
        OdedDvirO מנותק
        OdedDvir
        כתב ב נערך לאחרונה על ידי OdedDvir
        #23

        פרק כב: עושים סדר: חלק א: אפיון מדיוק של המערכת, טפסים רציפים

        המערכת שלנו בינתיים מסוגלת לכמה דברים, אבל לא מאורגנת בכלל.
        נו, אז הגיע הזמן לעשות קצת סדר.

        הזכרתי כבר שבמערכת אמיתית, שלב התכנון הוא הראשון, עוד בטרם ניגשים בכלל למחשב. פשוט לוקחים דף ועט ומציירים על הנייר. אין צורך לסרטט את הכל במחשב, לפחות לא בהתחלה. זה סתם מסרבל.

        אז לאחר שישבתי וחשבתי, הגעתי לאפיון המופיע בסרטוט הבא:

        1614046064616-תכנון-מערכת-תורמים.png

        המלבנים מייצגים טפסים והסנפירים למטה מייצגים את הפונקציונאליות שאני מבקש בטפסים אלו.
        את הדף הזה אני אתלה מול עיני בזמן הפיתוח, כך תהיה לי דרך סלולה ללכת בה, והכי חשוב: אני אדע ברור מתי כבר סיימתי. מעתה נשתדל להיצמד במדריך לאפיון הנ"ל.

        אגב, את התרשים הנ"ל יצרתי בעזרת כלי נפלא בשם Draw.io. זהו כלי מדהים ליצירת תרשימי זרימה, סרטוטים ועוד, קל ונוח, עם אפשרות לעברית מלאה, וקיים בגרסא מקוונת או להורדה, והוא חינמי לחלוטין!
        למי שעוקב אחרי ההדרכה, הנה הקובץ של הסרטוט

        תוכלו להכניס בו שינויים כרצונכם.

        סדר הפיתוח הנכון
        אני מאוד ממליץ להתחיל לבנות את המערכת מלמטה למעלה, כלומר קודם כל לבנות את הרבדים הנמוכים של המערכת, ומשם לטפס למעלה.

        נתחיל ברגל ימין עם צד ימין של המשפחות.
        ציינתי שיש שם טופס שמציג את רשימת המשפחות.
        מה אני רוצה שיראו בו?
        כמובן את פרטי המשפחה, ולפי האפיון, גם את סיכום התרומות למשפחה.

        לשם כך ניצור שאילתת עזר, שתקבץ את הנתונים של התרומות לפי משפחה.

        שלב א: יצירת שאילתת סיכום תרומות למשפחה
        נפתח שאילתה חדשה, נהפוך לשאילתת קיבוץ, נייבא את טבלת התרומות, ונגדיר את השדות לתצוגה באופן הבא:
        111fce0b-4441-4b5b-8dc0-f96431911c52-תמונה.png

        נשמור את השאילתה בשם qryFamily_DonationSummary

        שלב ב: יצירת השאילתת הבסיס לרשימת המשפחות:

        השאילתה הזו תושתת על צירוף של שתי השאילתות שיצרנו:

        • שאילתה א: שמות המשפחה המלאים: qryFamily_FullName
        • שאילתה ב: סיכום התרומות למשפחה: qryFamily_DonationSummary.

        נתבונן ונשים לב, שעלינו לצרף אותן בצירוף חיצוני, כי למרות שכל המשפחות מופיעות בשאילתה א (שמות המשפחה המלאים), שהרי היא מבוססת על טבלת המשפחות, יתכן ויש משפחה שלא תופיע בשאילתה ב (סיכום התרומות למשפחה), מפני ששאילתה ב מבוססת על טבלת התרומות, ותכיל רק משפחות שכבר יועדו להן תרומות.

        להלן מבנה השאילתה:
        4381e74d-38c4-4ad1-ae73-5b1bc9d1c284-תמונה.png

        נשמור את השאילתה בשם: qryFamily_FullName_DonationSummary
        כעת הכל מוכן ליצירת טופס רשימת המשפחות.

        תצוגת גליון נתונים .VS תצוגת טפסים רציפים

        לאקסס יש שתי אפשרויות להציג רשומות מרובות בטופס יחיד:

        • תצוגת גליון נתונים
        • תצוגת טפסים רציפים

        תצוגת גליון נתונים מציגה את הנתונים בטבלה פשוטה, בדומה לגליון אקסל. ולמרות שלעתים זה מספק, לרוב נרצה להשתמש בתצוגת טפסים רציפים, שמאפשרת גמישות רבה יותר.

        בואו נראה:
        נסמן את השאילתה שיצרנו, ונבחר מתפריט העיצוב: "טפסים נוספים" > "פריטים מרובים". אקסס תיצור טופס ותפתח אותו בתצוגת פריסה:
        8dea77e7-3cb1-490f-a7e7-cd59908ebbe8-תמונה.png

        נעבור לתצוגת עיצוב, ונראה כי באמת הטופס מחולק לשלושה חלקים (בדומה לדוח בפרק שעבר):
        78033e6c-202e-4d64-9b38-620aedb0aa20-תמונה.png

        • כותרת עליונה: משמשת בעיקר להצגת כותרות העמודות
        • פירוט: מציג את הרשומה הנוכחית
        • כותרת תחתונה: בה נשתמש להצגת סיכומי העמודות

        הערה: למרות שחלק הפירוט מראה שורה אחת בלבד, כשנעבור לתצוגת טופס יוצגו בפירוט כל הרשומות. כל עיצוב שנבצע בחלק זה - ישפיע על כל שורה ושורה בתצוגת הטופס.

        שלב ג: הוספת סיכום עמודות
        בואו ונרחיב את החלק של הכותרת התחתונה של הטופס, על ידי גרירה מטה של הגבול:
        2e0f9a4c-6c8d-4b8c-8ba9-b4b3d8020365-תמונה.png

        כעת נוסיף שם שלוש תיבות טקסט לא מאוגדות, ותווית אחת עם הכיתוב "סיכום", כפי שמופיע בתמונה הבאה:
        c23abceb-8b10-4b98-b32a-c8772615b7f8-תמונה.png

        בכל אחת מתיבות טקסט אני רוצה שיופיע סיכום של כל העמודה שמעליה.

        אבל לפני כן אנחנו חייבים לטפל בדבר חשוב.

        מי אני ומה שמי?

        לאקסס יש הרגל מגונה לתת לפקד מאוגד בטופס שם זהה לשם השדה בטבלה שאליו הוא מאוגד. למשל, תיבת הטקסט של שם המשפחה קיבלה את השם FullFamilyName, שזהה בדיוק לשם השדה FullFamilyName בטבלה שעליה מבוסס הטופס.

        בכך אקסס גורמת לי חוסר ודאות כמפתח המערכת, האם FullFamilyName מתייחס לתיבת הטקסט או לשדה בטבלה? וחוסר ודאות - זה מתכון מצוין לבעיות....

        לשם כך אני תמיד רגיל ביצירת טופס להפריד בין השניים, ולשנות את שם הפקד המאוגד לשם שונה משם השדה, על ידי הוספת קידומת מיוחדת לשם הפקד, לפי סוג הפקד.

        לדוגמא:

        • לתיבת טקסט אני אוסיף קידומת "txt"
        • לתווית אני אוסיף קידומת "lbl"
        • לתיבה משולבת אני אוסיף קידומת "cbo" וכו'

        זוהי אמנם עבודה מעט מרגיזה, אבל כמו תמיד, היא משתלמת מאוד כשמתחילים להוסיף קוד בטופס.

        לשם כך אני אשנה את שמות ארבע תיבות הטקסט המאוגדות בחלק הפירוט של הטופס, לפי הטבלה הבאה:

        שם קודם שם חדש
        ID txtID
        FullFamilyName txtFullFamilyName
        TotalDonationCount txtTotalDonationCount
        TotalDonationAmount txtTotalDonationAmount

        על ידי כניסה למאפיינים של הפקד (בלשונית "אחר" או בלשונית "הכל") והוספת הקידומת "txt" לשם הפקד, לדוגמא:
        d5d811da-d78a-48ed-a438-aa277d4ab3bf-תמונה.png

        הערה: יש הנוהגים להוסיף סיומת לשם הפקד (במקום קידומת) דהינו FullFamilyNameTextBox וכו', זה בהחלט אפשרי, אך לטעמי מסורבל יותר. והבוחר יבחר.

        למעשה, היינו צריכים להנהיג הנהגה זו כבר מתחילת המדריך, מהטופס הראשון שעשינו, אך נמנעתי מלהזכיר זאת עד עתה, פן ינחם העם בראותם מלחמה...
        על כל פנים, מעתה זו תהיה הנחת היסוד: מכאן והלאה לבצע את שינוי השם לכל שדה מאוגד בטופס.

        את הטיפול בכל הטפסים הקודמים נשאיר לשיעורי הבית (מסכן @בערל...)🤣

        סיימתם?
        כעת נוכל לבנות את הנוסחא לסיכום העמודות, נתחיל עם עמודת שמות המשפחה, שם אנו רוצים להציג את מספר המשפחות בטופס. נבחר את תיבת הטקסט שבכותרת התחתונה של העמודה של שמות המשפחה:
        d9a8af94-90b8-4b06-9f0d-2371ed68923e-תמונה.png

        במאפייני הפקד, בלשונית "נתונים" בחרו את המאפיין "מקור הפקד" ולחצו על שלושת הנקודות כדי לפתוח את בונה הביטויים:
        bc9be0a5-7aa4-48bd-955a-6b1c9bbd25e5-תמונה.png
        הקלידו בבונה את הנוסחה הבאה:

        Count(ID)
        

        עברו לתיבת הטקסט בתחתית העמודה השנייה, ושם תכניסו באותו אופן את הנוסחה:

        Sum(TotalDonationCount)
        

        ובתיבה האחרונה את הנוסחה:

        Sum(TotalDonationAmount)
        

        שנו גם את תבנית העיצוב של תיבה זו ל"מטבע":
        7a72548e-95ed-4785-bd82-a4322167eaa6-תמונה.png

        שלב ד: קצת קוסמטיקה:

        כבר הזכרתי שאני משתדל להימנע מלמרוח את הזמן על עיצובים, אך לפעמים זה פשוט נותן הרגשה טובה ונעימה יותר להמשיך בפיתוח, אז אני חורג מהרגלי פה ושם. עם זאת, אני משתדל לא להתפתות להתחיל לשנות את עיצוב כל הטפסים במערכת בשלב זה, כדי שלא להיתקע על קו עיצוב מסויים ולהיות משועבד לו מכאן ואילך, בפרט כשלרוב מחליטים לשנות אותו בהמשך...

        בחרו את כל הפקדים בכותרת התחתונה, ושנו את סגנון הרקע לשקוף, ואת צבע הכתב לשחור, עם סגנון מודגש:

        11fbe8c7-634d-4d39-986a-ffdc39f04505-תמונה.png

        לחצו על הפס האפור שעליו כתוב "כותרת תחתונה בטופס", והגדירו את צבע הרקע לתכלת:
        13d6e378-ee6c-4d5f-8ccc-24be69b10d1b-תמונה.png

        שנו גם הכותרת הראשית ואת תוויות הכותרת של העמודות לעברית.

        כעת עברו לתצוגת טופס, ושימו לב כי מופיעים סיכומים של העמודות בתחתית הטופס:
        36361dad-7192-4261-852b-0b90e2949e98-תמונה.png

        שלב ה: הוספת לחצנים לפונקציונאליות של הטופס
        כיוון שבא לידינו עיצוב טופס זה, נוסיף לו עוד שלושה לחצנים, אחד בכותרת העליונה להוספת משפחה למערכת, ושנים בחלק הפירוט: אחד לפתיחת כרטיס המשפחה ואחד למחיקת המשפחה מהמערכת (את הפונקציונאליות שלהם נממש בהמשך)
        נחזור לתצוגת עיצוב.
        בתפריט העיצוב, נבחר את לחצן הפקודה מסרגל הפקדים:
        26d8ab9b-42f4-4af9-a521-4e057847c6df-תמונה.png

        נקליק בכותרת העליונה של הטופס במקום שבו אנו רוצים ליצור את הלחצן:
        3744000f-8a19-4268-83cc-91520a94a7f3-תמונה.png

        אקסס תיצור לחצן עם השם "פקודהXX" ותפתח את אשף לחצני הפקודות, שאליו נסרב להתייחס ופשוט נסגור אותו בנימוס, על ידי לחיצה על "ביטול":
        1258d4e3-9014-4dfc-876c-19b75bc92bd3-תמונה.png

        האשף הנ"ל מציע ליצור עבורנו פקודות מאקרו לבניית הפונקציונאליות של הלחצנים, אך אנו נכתוב זאת בעצמנו על ידי קוד VBA בהמשך.

        נשנה את שם הלחצן ל cmdNewFamily ואת הכיתוב עליו ל"משפחה חדשה":
        55353fca-5237-4369-bc98-25a0094d5df7-תמונה.png

        נוסיף עוד שני לחצנים בחלק הפירוט של הטופס, אחד מימין בראש השורה, בשם cmdOpenFamilyCard ועם הכיתוב "הצג", ואחד משמאל בסוף השורה בשם cmdDeleteFamily עם הכיתוב "מחק":
        9c07f54d-717c-4053-bae9-fa24027ddfef-תמונה.png

        כעת אין צורך בבוררי הרשומות ולחצני הניווט של הטופס, אז בואו נסיר גם אותם (בחרו קודם בפקד הטופס, בפינה השמאלית העליונה, זוכרים?)
        6a4d2224-b1a0-476a-b112-7cd21b483ef6-תמונה.png

        כשנסיים, נשמור את הטופס בשם frmFamilyList.

        והנה הטופס המוכן, אחרי עוד כמה קנעטשים:
        dd771665-459d-4eb7-adfc-bd0667ae511e-תמונה.png

        בפרק הבא ניצור גם את טופס כרטיס המשפחה, ונוסיף פונקציונאליות ללחצנים שיצרנו היום.

        תגובה 1 תגובה אחרונה
        15
        • OdedDvirO מנותק
          OdedDvirO מנותק
          OdedDvir
          כתב ב נערך לאחרונה על ידי OdedDvir
          #24

          פרק כג: עושים סדר: חלק ב: שדרוגים שונים, פונקציונאליות לחצני רשומה, ורגע למחשבה.

          תזכורת:

          בפרק הבא ניצור גם את טופס כרטיס המשפחה, ונוסיף פונקציונאליות ללחצנים שיצרנו היום.

          גילוי נאות: בפרק זה עדיין לא נוסיף פונקציונאליות ללחצנים הנ"ל, אלא ללחצנים אחרים שניצור.

          שלב א: שדרוג כרטיס המשפחה
          בואו ניזכר, כי בפרק יד יצרנו כבר טופס בשם frmFamily המציג את פרטי המשפחה, אם כי הוא לא מעורר תיאבון במיוחד:
          0abff085-967f-4841-9294-f3551adc0921-תמונה.png

          שינוי השם
          ראשית נשנה את שמו לשם חדש: frmFamilyCard (כרטיס משפחה), שמתאים יותר לתכנית שלנו מהפרק הקודם:
          2f7cf3bd-da4e-4022-b371-8cd855879647-תמונה.png

          הצגת מידע על התרומות המשוייכות
          מלבד תצוגה של כל פרטי המשפחה, אני רוצה להציג בטופס זה גם סיכום קצר על התרומות שמשוייכות למשפחה זו.
          כבסיס, אפשר להשתמש בשאילתת סיכום התרומות למשפחה שיצרנו בעבר: qryFamily_DonationSummary, אבל היא לא מספיק מפורטת, כי היא מציגה רק את סכום כל התרומות למשפחה, מבלי להתייחס לסטטוס התרומות.

          לדוגמא, עבור משפחת אשרי, מופיע שקיימות 2 תרומות על סך כולל 300 ₪:
          75cbdbd0-1cc6-4f53-a93c-47bb919a22b1-תמונה.png

          אבל אין שום מידע על סטטוס התרומות, מה בוצע ומה לא.

          לצורך המחשת העניין, נפתח את טבלת התרומות ונשנה את הסטטוס של התרומה הראשונה ל-בוצעה:
          980cfebd-1f34-403f-b1ba-16fbf0635c5d-תמונה.png

          כעת למשפחת אשרי יש 100 ₪ שבוצעו ו-200 ₪ שממתינים לביצוע, אך שאילתת הסיכום הנ"ל לא מציגה שום מידע על השינוי שעשינו כעת:
          4efdeadb-8e08-4d13-a6f9-1a22003163d1-תמונה.png

          שלב ב: שדרוג שאילתת סיכום התרומות
          בואו נשדרג את שאילתת הסיכום, כך שתציג עוד ארבע עמודות חדשות:

          1. AwaitingDonationCount מספר התרומות הממתינות לביצוע (=המיועדות)
          2. AwaitingDonationSum סכום התרומות הממתינות לביצוע (=המיועדות)
          3. DoneDonationCount מספר התרומות שבוצעו בפועל
          4. DoneDonationSum סכום התרומות שבוצעו בפועל

          נתחיל ע"י פתיחת השאילתה בתצוגת עיצוב, וניצור שדה חדש בשם AwaitingDonationCount:
          be471666-b59b-42a9-a84a-f812975efb0a-תמונה.png

          אבל מה תהיה הנוסחה שבה נשתמש?
          יש כאן קושי מסויים, כי לחישוב השדה הזה אי אפשר להשתמש בפונקצית Count רגילה, מפני שאז נקבל את מספר כל הרשומות, ואנו מעוניינים לקבל רק את מספר התרומות שמיועדות אך לא בוצעו עדיין, דהיינו עם סטטוס=2.

          הפתרון הוא ליצור שדה עם ביטוי מחושב. נפתח את הבונה:
          60df9360-f223-425a-882c-48f442c30a17-תמונה.png

          ונרשום את הנוסחא הבאה:

          AwaitingDonationCount: Sum(IIf([StatusID]=2,1,0))
          

          הסבר: נוסחא זו מחשבת סכום לפי תנאי IIF: עבור כל רשומה, אם StatusID=2 (התרומה מיועדת), מוסיפים לסכום את הערך 1, אחרת – מוסיפים 0.

          נסגור את הבונה, ונשנה את המאפיין "סך הכל" מ-"קבץ לפי" ל-"Expression", כדי להורות לשאילתה שכאן מדובר בביטוי מחושב ולא בשדה רגיל:
          9573b50e-153b-4f3a-ab60-cafc5921164b-תמונה.png

          נעבור לתצוגת גליון נתונים ונראה כי הערך המופיע עבור משפחת אשרי הוא 1, דהיינו שיש לה תרומה אחת משוייכת:
          fb0cd538-5b0c-45c7-b3aa-63d218cf74e4-תמונה.png

          יפה. כעת ניצור את השדה השני: סכום התרומות המשוייכות - בצורה דומה:
          נוסיף שדה חדש בשם AwaitingDonationSum, אך הפעם במקום להוסיף לסכום המחושב את הערך 1, נוסיף את סכום התרומה הנוכחית ברשומה:

          AwaitingDonationSum: Sum(IIf([StatusID]=2,[Amount],0))
          

          ושוב, נשנה את סוג השדה ל-Expression.

          כעת מוצג גם הסכום של התרומות המיועדות:
          68a151b6-4dc0-4d41-929a-f84a1004e10d-תמונה.png

          באופן דומה נוסיף את שתי העמודות הנותרות, עם הנוסחאות הבאות:
          מספר התרומות שבוצעו בפועל: DoneDonationCount: Sum(IIf([StatusID]=3,1,0))
          סכום התרומות שבוצעו בפועל: DoneDonationSum: Sum(IIf([StatusID]=3,[Amount],0))

          הערה: למרות שאפשרי (ואפילו יותר יעיל), לחשב את שתי השדות האחרונים בלי להשתמש בעוד פונקציית סכום, אלא פשוט על ידי ההפרש בין שתי השדות הקודמים, דהיינו:
          DoneDonationCount: TotalDonationCount - AwaitingDonationCount
          לא כדאי לנו לעשות כן, כי אם נחליט אי פעם להוסיף למערכת ערך סטטוס תרומה חדש, למשל: "בוטלה" (כשהתרומה הוקלדה בטעות, או שהבנק לא אישר את ההעברה), השדה המחושב יתעלם מסטטוס זה, ועלול להציג ערך שגוי.

          והנה התוצאה הסופית:
          6919eb19-c184-4cfc-ad9c-4282c57fd8e2-תמונה.png

          שלב ג: יצירת טופס משנה לתרומות
          כעת ניצור טופס המציג את השדות, נתחיל כמו בעבר על ידי בחירת השאילתא ויצירת טופס אוטומטי:
          6b7fd67f-d145-4d9b-88b7-094cb7943860-תמונה.png

          ונבצע את השינויים הבאים:
          בתיבות הטקסט: הוספת קידומת "txt", הסרת הגבול, הקטנת הרוחב ל-3 ס"מ.
          בטופס: מחיקת תיבת הטקסט והתווית של משפחת היעד, הסרת בוררי הרשומות, הסרת לחצני הניווט, שינוי הכותרת, הקטנת הרוחב ל-8 ס"מ.

          התוצאה:
          ceb58a32-3a19-42cc-bc73-ff6572afddc2-תמונה.png

          שמרו את הטופס בשם: frmFamily_DonationSummary.

          נוסיף אותו כטופס משנה לכרטיס המשפחה, על ידי גרירה:
          9d42dc60-a846-4b96-a3d3-e671553836f9-תמונה.png

          נעבור למאפייני פקד טופס המשנה, ונראה שאקסס לא ביצעה קישור בין נתוני טופס המשנה לטופס האב:
          9bfc62a5-e0f7-4393-b12c-5e3e361f73b2-תמונה.png

          מדוע המאפיינים ריקים?
          כשהטפסים מבוססים על טבלאות, ויש בין הטבלאות קשרי גומלין, אקסס מזהה את השדה המקשר ומגדירה את הקישור אוטומטית. אך כאן טופס המשנה מבוסס על שאילתה ולא על טבלה, ולכן לא זכינו לפינוק הזה.

          נו טוב, נעשה זאת בעצמנו, אבל אל דאגה, אקסס עוזרת לנו גם כאן, ומספקת מנגנון פשוט לקישור בין הטפסים.

          נבחר את אחד המאפיינים קישור שדות אב או קישור שדות צאצא, ונלחץ על שלש הנקודות:
          5d311ae0-8aa8-4dee-8a1c-2b0b47c80996-תמונה.png

          ייפתח החלון הבא:
          6954bcb3-c42f-42c9-8cba-348de90213ca-תמונה.png

          הופה!
          אקסס ניסתה לנחש את השדות המקושרים ו... הצליחה!
          יתרה מכך, אקסס מתארת עבורנו את התוצאה שתתקבל מקישור זה:
          3a05f68d-6dde-4539-91cb-5a2f2d9a299b-תמונה.png

          נשמע טוב.
          לנו נשארה המלאכה המפרכת ללחוץ על אישור... ואקסס תעדכן את המאפיינים:
          d82f635c-7335-4181-ba08-6ca0a4800d48-תמונה.png

          נסיים את העבודה על הטופס הזה:

          1. נשנה את העוגן האופקי של פקד טופס המשנה ל: ימין, כך שיוצג בצמוד לפרטי המשפחה:
            7b409599-dcce-462e-9b55-316af4782bea-תמונה.png
          2. נסיר את השדה המזהה ID.
          3. נעביר את תיבת הטקסט של CreatedOn לראש, ונשנה את המאפיין "נעול" ל-כן, והמאפיין "אפשר" ל-לא. כך נמנע מהמשתמש לבצע בה שינוי בטעות. אני גם אוהב להסיר לגמרי את הגבול מתיבות טקסט לקריאה בלבד, ולכן אעשה גם את זה.
          4. נשנה את הכיתוב בתוויות.
          5. נוסיף עוד שני לחצנים בכותרת, אחד בשם cmdNew לפתיחת כרטיס חדש, ואחד בשם cmdDelete למחיקת הכרטיס הנוכחי.

          הנה התוצאה:
          333244c6-dd79-467d-923b-8e38f8725005-תמונה.png

          נעבור למשפחת אשרי ונוודא שטופס המשנה מתעדכן נכון כשעוברים ממשפחה למשפחה, ומציג את פרטי התרומות הנכונים:
          8be34c92-903f-4906-87ca-d4871399b37a-תמונה.png
          נפלא!

          שלב ד: הוספת פונקציונאליות בלחצני כרטיס המשפחה
          נבחר את לחצן יצירת כרטיס חדש cmdNew שיצרנו הרגע, ובמאפיינים בלשונית "אירוע", נבחר את האירוע: "בעת לחיצה", ונבחר את האפשרות "פרוצדורת אירוע":
          bbc9045f-9036-4609-98dc-e2627d4c2784-תמונה.png

          נלחץ על שלושת הנקודות … אקסס תפתח את עורך הקוד, ותיצור שלד לפונקציית האירוע.

          1ce3c08f-c141-4061-99fa-995edf35568d-תמונה.png

          שימו לב לשם הפונקציה: הוא מתחיל בשם הפקד cmdNew, ומסתיים בסיומת Click כסימן שהפונקציה משוייכת לארוע הלחיצה של הפקד.

          נרשום את הקוד הבא:

          Private Sub cmdNew_Click()
              DoCmd.GoToRecord , , acNewRec
          End Sub
          

          הסבר הקוד:
          בשפת VBA קיימים אובייקטים שונים.

          אובייקט הוא מושג בסיסי במדעי המחשב המתאר משתנה, פונקציה, מבנה נתונים או שילוב של הנ"ל.

          אחד האובייקטים הנכבדים באקסס הוא DoCmd שמאגד בתוכו פונקציות רבות ומגוונות, כגון שליטה על חלונות וטפסים.
          אחת מהפונקציות שהוא מכיל היא: GoToRecord שתפקידה, כמובן, לבצע מעבר בין רשומות.
          ניתן לספק לה 4 פרמטרים, וכולם אופציונאליים.

          אנחנו דילגנו על שני הפרמטרים הראשונים על ידי ציון של פסיק, וסיפקנו רק את הפרמטר השלישי: acNewRec שפירושו "רשומה חדשה".

          נחזור לאקסס על ידי Alt+F11, נעבור לתצוגת טופס, ונבדוק שלחיצה על הלחצן מעבירה אותנו לרשומה חדשה.
          פשוט וקל!

          כעת ללחצן המחיקה
          נחזור לתצוגת עיצוב, נבחר כעת את לחצן המחיקה, וניצור פונקציית אירוע גם עבור ארוע הלחיצה שלו:
          b4989c57-f720-4875-8e85-52e8e8bd6f7c-תמונה.png

          הפעם נרשום את הקוד הבא:

          Private Sub cmdDelete_Click()
              DoCmd.RunCommand acCmdDeleteRecord
          End Sub
          

          הסבר: כאן אנו קוראים לפונקציה אחרת (באובייקט DoCmd) ששמה RunCommand, ומספקים לה פרמטר אחד: acCmdDeleteRecord, שפירושו: מחיקת הרשומה הנוכחית.

          בואו נבדוק את הלחצן. נחזור לאקסס Alt+F11, נעבור לתצוגת טופס וננסה למחוק את משפחת ראובני...
          אופס! אקסס תציג את הודעת השגיאה הבאה:
          96b751e4-22b3-461a-861a-40ed29df4434-תמונה.png

          מה קרה? שימו לב ללשון ההודעה.

          בעצם הכל תקין. אקסס לא מאפשרת לנו למחוק את הרשומה, ויש לכך סיבה טובה מאוד! אנו מנסים בעצם למחוק את הרשומה של משפחת ראובני מהטבלה Family, אך ניזכר כי הטבלה Family מקושרת בקשר גומלין לטבלת הזוגות Family_Donor, וזו מכילה רשומות השייכות למשפחת ראובני (כי ישנם תורמים המשוייכים למשפחה זו).

          כיון שבהגדרת קשרי הגומלין, הגדרנו לאכוף את שלימות קשרי הגומלין בין הטבלאות, אם נמחק את משפחת ראובני רק מטבלת המשפחות, נהפוך את כל הרשומות של משפחת ראובני בטבלה Family_Donor לרשומות יתומות, כי אין להם שדה אב מתאים בטבלת Family. בסיס הנתונים יכיל נתונים לא שלמים.

          אקסס דואגת שלא נגיע לידי כך, וזה דבר טוב.

          אז מה עושים?

          מחיקות הירארכיות
          כדי לאפשר מחיקה של רשומה בטבלת המשפחות, אנו חייבים להורות בפירוש לאקסס למחוק גם את כל הרשומות הקשורות אליה בשאר הטבלאות, בהתאם להירארכיית הקשרים. לשם כך נערוך את קשרי הגומלין בין הטבלאות.

          נפתח את עורך קשרי הגומלין ונקליק פעמיים על החץ המקשר בין הטבלאות Family ו-Family_Donor:
          55cb7469-9fa0-409c-aea4-a44c3805b1e4-תמונה.png

          ייפתח חלון עורך קשרי הגומלין, ונסמן ב-V את האפשרות: מחק רשומות קשורות זו לזו בהתאם להירארכיית הקשרים:
          dd102387-ccda-4b83-a5ee-46425108270d-תמונה.png
          נלחץ על אישור.
          זהו.
          כעת ברגע שנמחק משפחה, אם יש לה תורמים משוייכים, אקסס פשוט תמחק אוטומטית את הרשומות המתאימות גם בטבלה Family_Donor.

          רגע, חושבים!
          שימו לב כי הטבלה Family מקושרת בקשרי גומלין גם לטבלת התרומות Donation, וגם שם בחרנו לאכוף את שלמות הקשרים בין הטבלאות.
          לכאורה זה אומר שפתרנו רק חצי בעיה, כי אם תהיה למשפחה גם תרומה משוייכת – לא נוכל למחוק אותה.

          מה הבעיה, אפשר להגדיר מחדש גם את קשר הגומלין הזה, וכאשר נמחק משפחה - לאפשר לאקסס למחוק את התרומות המשוייכות אליה, לא?

          אז זהו, שממש לא.
          חישבו, האם באמת כדאי לנו לאפשר מחיקה של נתוני תרומות? ומה אם נרצה להוציא דו"ח על כל התרומות שעברו בעמותה שלנו? ואם נצטרך להגיש דוח למס הכנסה?! 😕 😬

          לכן - לא ניגע בקשר הגומלין הזה. ואם יש למשפחה תרומה משוייכת - לא נאפשר מחיקה שלה בכלל.

          מכאן עולה המסקנה הבאה:

          שימוש במחיקות הירארכיות הוא מנגנון מסוכן, ומצריך מחשבה מקדימה. למעשה ישנם מתכנתים הנמנעים מלאפשר זאת על ידי קשרי הגומלין, ומעדיפים להשאיר את האחריות בידיים שלהם. כאשר הדבר נצרך, כגון הכא - הם מבצעים מחיקה של הרשומות בטבלאות הקשורות, על ידי קוד, ורק לאחר שבע בדיקות שאין כאן טעות.

          ומדוע אפשרנו זאת במקרה של התורמים המשוייכים?
          מפני שטבלת הזוגות Family_Donor בסך הכל מציינת קשר גומלין של רבים לרבים, ומחיקת רשומה ממנה אינה משפיעה על טבלת נתוני התורמים בשום צורה, ובוודאי שאינה מוחקת שום תורם, לכן היא בטוחה.

          המשך יבוא אי"ה...

          תגובה 1 תגובה אחרונה
          16
          • OdedDvirO מנותק
            OdedDvirO מנותק
            OdedDvir
            כתב ב נערך לאחרונה על ידי OdedDvir
            #25

            פרק כד: עושים סדר: חלק ג: תפריטים ופקדי ניווט, פונקציונאליות ברשימת המשפחות

            שלום לכולם! מקווה שנהנתם מהחופש הגדול...

            היום הגענו לחלק די קל ומהנה (יחסית...) והוא בניית התפריטים.

            אחד הדברים שחסרים מאוד במערכת שלנו הוא התפריט הראשי, (או הדשבורד), שדרכו ננווט את דרכנו בין הטפסים השונים, במקום לבחור בכל פעם את הטופס מהפנל מימין.

            אני רוצה ליצור משהו כזה:
            929e98e0-7562-4e49-a60f-0a3e19ce26ba-תמונה.png

            למרבה המזל, לאקסס יש מנגנון מובנה לניהול הניווט בין טפסים, בשם פקד הניווט.
            אז בואו ניצור משהו כזה.

            שלב א: יצירת טופס תפריט המשפחות
            נפתח טופס חדש ריק, על ידי יצירה > עיצוב טופס.
            נבחר מתפריט העיצוב את פקד הניווט:
            61ed66c8-6c6a-49f5-8bf9-5a4114bce9a8-תמונה.png

            ואז פשוט נקליק בתוך הטופס קרוב לפינה הימנית העליונה:
            0d5c7b84-09e4-4a24-8d64-f05976996eb5-תמונה.png

            אקסס תיצור עבורנו פקד ניווט:
            779206f3-882f-4bbc-b756-7694ed7498e8-תמונה.png

            לפקד הניווט שני חלקים:

            1. החלק העליון הוא פקד הניווט עצמו, זהו בעצם התפריט, שמכיל את הלחצנים לבחירת הטפסים לתצוגה.
            2. החלק התחתון הוא פקד טופס המשנה לניווט, ותפקידו להציג בתוכו את הטפסים שבחרנו מן התפריט.
              הערה חשובה: כברירת מחדל, שם פקד טופס המשנה הוא "NavigationSubform". למרות שאפשר לשנות את שמו לכל שם שנרצה, לעת עתה נשאיר אותו עם שם זה. פרט זה יתגלה כחשוב בהמשך הדרך.

            נוסיף לחצן לפקד הניווט על ידי לחיצה על המקום שמסומן [הוסף חדש], ונרשום בתוכו "רשימת משפחות". אקסס יצרה עבורנו לחצן חדש:
            a1142b9b-6195-4492-8f19-eaa454574989-תמונה.png

            נגדיל את הלחצן כך שיציג את כל הכיתוב:
            758a4992-e004-4c80-a6b5-d7411662a887-תמונה.png

            נוסיף עוד לחצן עם הכיתוב "כרטיס משפחה":
            cff8531e-602b-4a9d-bb4e-9efaf52ce9d0-תמונה.png

            כעת נותר לנו להגדיר איזה טופס ייפתח על ידי כל לחצן.
            ניכנס למאפיינים של הלחצן הראשון (רשימת המשפחות), ובלשונית הנתונים נבחר את המאפיין "שם יעד ניווט", ונבחר מתיבת הרשימה המשולבת את טופס רשימת המשפחות frmFamilyList:
            51f0751a-69df-48cc-91c1-d5cde737dad6-תמונה.png

            באופן דומה, גם בלחצן השני, נבחר את שם יעד הניווט להיות טופס כרטיס המשפחה frmFamilyCard:
            4da4aa8a-1182-4f17-af7f-856644ad27da-תמונה.png

            לסיום, נסיר מן הטופס את הפקדים המיותרים: בוררי הרשומות, לחצני ניווט ופסי הגלילה: (להלן: "שלשת המעצבנים")
            50efdb0e-dfef-428f-a7ca-f51e02ffd7c0-תמונה.png

            ונצמצם את השוליים המיותרים מסביב לפקד הניווט (מסומנים בכתום):
            d673cde3-9d38-4c66-85f1-cd7651ad2743-תמונה.png
            נסגור את הטופס ונשמור אותו בשם navFamilies.
            כעת פתחו את הטופס שיצרנו ובידקו את לחצני הניווט:
            33298f0e-8cb3-45a3-9509-2ec6ca431b0a-תמונה.png

            1bc0fe86-ab00-4812-8ef3-d9ce8b3dc785-תמונה.png

            שלב ב: יצירת טופס התפריט הראשי
            בדומה לשלב הקודם, נפתח טופס חדש ריק, על ידי יצירה > עיצוב טופס, ונוסיף אליו פקד ניווט, ונוסיף שלושה לחצנים כפי שמופיע בתמונה הבאה:
            b0fefc87-12a4-45e7-a8f3-ed955d07a0ee-תמונה.png

            כעת נהפוך את הכיוון של התפריט לאנכי.
            לשם כך נבחר את פקד הניווט כולו (זוכרים? החלק העליון) על ידי הקלקה במקום הריק (לא על לחצן):
            c79ac8cc-4754-420f-a1d9-59007a192374-תמונה.png

            שימו לב שכל פקד הניווט מסומן כעת.
            מתוך המאפיינים בלשונית התבנית נגדיר את המאפיין "מרחב" ל-"אנכי". שימו לב לשינוי בפריסת הלחצנים, כעת הם מופיעים מלמעלה למטה:
            cc6ce00b-e005-465f-b735-660af708bd7e-תמונה.png

            אך עדיין פקד הניווט מופיע בצמוד לחלק העליון של טופס המשנה, ולא מצידו הימני כמו בתכנון.
            אל דאגה, נשנה זאת מיד: נגרור את כל פקד הניווט, כך שיופיע בצמוד לדופן הימנית של טופס המשנה.
            שימו לב לגרור אותו אל הדופן הימנית ממש, כך שיוצג קו בצבע ורוד חלש בצד ימין:
            240fd155-ddf3-4577-8221-4ba8e4e3a283-תמונה.png

            כעת נקטין את רוחב פקד הניווט לגודל יותר סביר:
            26b9919a-dd02-40f6-b134-528f7af8257e-תמונה.png

            נגדיר את שם יעד הניווט עבור לחצן המשפחות להיות טופס תפריט המשפחות שיצרנו היום: navFamilies. (בינתיים יש לנו רק את תפריט המשפחות, את שני התפריטים של התורמים והתרומות ניצור בהמשך.)
            לסיום – גם כאן נסיר את הפקדים המיותרים בטופס (שלשת המעצבנים כדלעיל), ואת השוליים המיותרים מסביב לפקד הניווט.
            נשמור את הטופס בשם navMain.

            להלן התוצאה:
            9d35ed40-74d8-4c8e-9561-7f64ac3fe405-תמונה.png

            נהדר, זה לא היה קשה, נכון?

            קחו אויר, כי החלק הבא קצת יותר מורכב.

            שלב ג: הוספת פונקציונאליות ללחצנים שבטפסים
            נשאר לנו כעת לחבר את הלחצנים שבטפסי המשפחה (אלו שיצרנו בפרק כב). נתחיל עם טופס רשימת המשפחות.

            לחצן תצוגת המשפחה
            פתחו את הטופס בתצוגת עיצוב, ובחרו את לחצן הצגת המשפחה. שנו את שמו ל: cmdViewFamilyCard:
            14cfc6d5-ef64-4b6b-90d5-9bee54fd7eb7-תמונה.png

            כעת נגדיר פונקצית אירוע לחיצה:
            בלשונית אירוע, בחרו את האירוע בעת לחיצה, ופתחו את בונה הקוד על ידי לחיצה על שלושת הנקודות … ובחירה באפשרות בונה הקוד.
            אקסס תיצור תבנית עבור פונקצית הארוע של הלחצן.
            הוסיפו בגוף הפונקציה את השורה הבאה:

             DoCmd.BrowseTo acBrowseToForm, "frmFamilyCard", "navMain.NavigationSubform>navFamilies.NavigationSubform", "ID=" & Me.ID
            

            הסבר הקוד:
            אנו משתמשים כאן באובייקט DoCmd שראינו בעבר, המכיל פונקציות שונות באקסס. מתוכו אנו מפעילים את הפונקציה BrowseTo שתפקידה לנווט אל טופס מסויים. הפונקציה מקבלת כמה פרמטרים:
            65ae142a-605d-4230-9469-b47200ef9bbb-תמונה.png

            • הפרמטר הראשון acBrowseToForm מציין את סוג האובייקט לתצוגה. במקרה שלנו הוא טופס.

            כדי להציג דוח במקום טופס, יש לציין acBrowseToReport במקום acBrowseToForm.

            • הפרמטר השני "frmFamilyCard" מציין את שם הטופס לפתיחה הלא הוא כרטיס המשפחה.
            • הפרמטר השלישי "navMain.NavigationSubform>navFamilies.NavigationSubform" מציין את הנתיב שבו ייפתח הטופס.
              כיוון שבנינו מערכת של תפריטי ניווט מקוננים (תפריט ראשי>תפריט המשפחות) אנו צריכים לציין במפורש את כל המסלול שדרכו נגיע ליעד המבוקש (טופס המשנה של תפריט המשפחות). התחביר הוא כך:
              שם_טופס_הניווט.שם_פקד_טופס_המשנה (כברירת מחדל הוא NavigationSubform)
              אם יש כמה טפסי ניווט אחד בתוך השני (כמו אצלנו), מפרידים ביניהם על ידי הסימן "גדול מ" <.
              כך מתקבלת התוצאה הנ"ל.

            שימו לב שיש להוסיף גרשיים מסביב לנתיב, כי הוא צריך להיות מועבר לפונקציה כמחרוזת.

            • הפרמטר הרביעי "ID=" & Me.ID מציין קריטריון לחיפוש רשומה מבוקשת לתצוגה.
              פרמטר זה הוא אופציונאלי, וכאשר מציינים אותו, אקסס תחפש בטופס שנפתח את הרשומה המתאימה לקריטריון, ותקפוץ אליה בפתיחת הטופס.
              לדוגמא, אם אנו רוצים להציג את המשפחה שהמזהה ID שלה הוא 7, עלינו להעביר לפונקציה את הקריטריון: "ID=7".
              הואיל וברצוננו להציג את המשפחה המתאימה לשורה שבה לחצנו על הלחצן, ואנחנו לא יודעים מה יהיה המזהה שלה, נוכל לקבל את המזהה שלה על ידי האובייקט Me.ID וניצור את הקריטריון המתאים על ידי חיבור מחרוזות.

            הערה: ההסבר לעיל עלול לבלבל מאוד מתכנתים בתחילת הדרך.
            אם אתם כאלו, זה נורמלי לחלוטין, ואין צורך להיבהל. כתיבת והבנת קוד, כמו כל מיומנות, הולכת ומשתפרת עם תרגול.
            כמובן שישנה גם האפשרות שההסבר שלי לא מספיק ברור...
            בכל מקרה, אל תזיעו יותר מידי. אני מבטיח שהעסק נהיה יותר קל עם הזמן.

            שימרו את הטופס.
            כעת פיתחו את טופס התפריט הראשי navMain, בחרו את תפריט המשפחות, וברשימת המשפחות בידקו שהלחצן "הצג" עובד כראוי.

            טעות בכתובת
            הניווט של אקסס אינו מושלם.
            נסו לפתוח ישירות את הטופס של רשימת המשפחות frmFamilyList, וללחוץ על הלחצן "הצג".
            למרבה התסכול, במקום להציג את הטופס, אקסס תציג הודעת שגיאה:
            ad51c3b1-8ab4-4465-b976-e8857dd3fd0e-תמונה.png

            מה קרה?
            ההודעה הזו מוצגת מפני שאנו מנסים לגשת לנתיב שאינו קיים.
            הרי בקוד צייננו שהנתיב המבוקש הוא "navMain.NavigationSubform>navFamilies.NavigationSubform". אבל הטפסים של הניווט navMain ו-navFamilies לא פתוחים כעת, ולכן הנתיב שגוי.

            ישנה אפשרות על ידי קוד לפתור את הבעיה הנ"ל, אך לעת עתה נניח לה במקומה, ולא נלחץ על הכפתור הצג אם התפריטים לא פתוחים.

            לחצן יצירת משפחה חדשה
            בואו ניצור גם את הלחצן של יצירת משפחה חדשה. נבחר את הלחצן, וניצור עבורו פונקצית אירוע בעת לחיצה:
            1e7bf761-05a7-43ec-8dff-e66bf5dbd51e-תמונה.png

            לשמחתנו, הקוד הנדרש דומה לקוד הקודם (נוכל להעתיק ולהדביק, ולשנות כנדרש):

            DoCmd.BrowseTo acBrowseToForm, "frmFamilyCard", "navMain.NavigationSubform>navFamilies.NavigationSubform", , , acFormAdd
            

            הסבר הקוד:
            השמטנו את הפרמטר הרביעי (כי אנו לא רוצים לקפוץ לרשומה מסויימת), וגם את הפרמטר החמישי (לא רלוונטי כעת).

            • הפרמטר השישי acFormAdd מורה לאקסס לפתוח את הטופס המבוקש במצב הוספת נתונים, ולהציג רשומה חדשה בטופס.

            שימרו את הטופס, פתחו את התפריט הראשי ובידקו שלחצן יצירת משפחה חדשה עובד כראוי.

            לחצן מחיקת המשפחה
            מחיקת משפחה היא תהליך מורכב, הואיל ויש לכל משפחה קשרי גומלין שונים. בנוסף, אני לא בטוח שכדאי לאפשר מחיקת משפחה מתצוגת הרשימה. לכן אני אחזור בי ואסיר את לחצן המחיקה מרשימת המשפחות, כדי לאפשר מחיקת משפחה רק מכרטיס המשפחה:
            8cb6114f-a2b9-4c8e-9a41-ad0ffb38f4c0-תמונה.png

            את הקוד עבור לחצני כרטיס המשפחה (כולל מחיקת משפחה) נשאיר לפעם הבאה אי"ה.

            תגובה 1 תגובה אחרונה
            31
            • OdedDvirO OdedDvir התייחס לנושא זה ב
            • OdedDvirO OdedDvir התייחס לנושא זה ב
            • OdedDvirO OdedDvir התייחס לנושא זה ב
            • צבי-שצ צבי-ש התייחס לנושא זה ב
            • OdedDvirO OdedDvir התייחס לנושא זה ב
            • A0533057932A A0533057932 התייחס לנושא זה ב
            • ס סקרן 0 התייחס לנושא זה ב
            • OdedDvirO OdedDvir התייחס לנושא זה ב
            • מלאמ מלא התייחס לנושא זה ב
            • O one1010 התייחס לנושא זה ב
            • OdedDvirO OdedDvir התייחס לנושא זה ב
            • dovidD dovid התייחס לנושא זה ב

            • 1
            • 2
            בא תתחבר לדף היומי!
            • התחברות

            • אין לך חשבון עדיין? הרשמה

            • התחברו או הירשמו כדי לחפש.
            • פוסט ראשון
              פוסט אחרון
            0
            • דף הבית
            • קטגוריות
            • פוסטים אחרונים
            • משתמשים
            • חיפוש
            • חוקי הפורום