Northwind 2.0 דברים שכדאי לדעת

חל על
Access של Microsoft 365 Access 2021 Access 2019

התוכן כאן עשוי לחול על Northwind 2.0 Developer Edition ועל Starter Edition. 

חומר עזר בנושא Access VBA

VBA (Visual Basic for Applications) היא שפת התיכנות המשמשת את כל מוצרי Office. למידת VBA מאפשרת לך לעבוד עם כל מוצרי Office (לא רק Access).
בעת חיפוש אחר "כיצד לבצע", הקפד לחפש דוגמאות ספציפיות של Access ולכלול את Microsoft Access בחיפוש. לעתים קרובות פתרונות עבור מוצרי Office האחרים יעבדו - אך אין ערובה. Microsoft Access הוא מוצר למבוגרים; זה אומר שיש הרבה דוגמאות בחוץ; וזה נהדר בשבילך! 

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

משאבי סיום התמיכה עבור Office - פריסת Office | Microsoft Learn

להלן כמה קישורים לתיעוד של Access ב- Microsoft.

מיקומים מהימנים ותוכן זמין

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

קבל מידע נוסף על מיקומים מהימנים.:

פקודות מאקרו, פונקציות ותתי

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

אירועים (כגון לחיצה על פקד) בפקדים בטופס (לדוגמה, לחצנים, תיבות טקסט, תוויות וכדומה) מפעילים תהליכים אחרים, כגון הוספה, מחיקה של רשומות או פתיחת טפסים. ניתן ליישם תהליכים אלה באמצעות פקודות מאקרו או VBA. Northwind Starter Edition משתמשת בעיקר בפקודות מאקרו ובמעט VBA שבו פקודות מאקרו אינן מסוגלות לבצע פונקציות נחוצות. Northwind Developer Edition משתמשת בעיקר ב- VBA. 

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

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

טווח וניראות של משתנים ב- VBA

חשוב ללמוד אודות טווח וניראות ב- Access/Office. באפשרותך להתחיל כאן:

משתנים מתמידים

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

משתנה ציבורי של מודול VBA:

TempVars:

אחסון הערכים בטבלה מקומית

  • משתנים ציבוריים ו- TempVars קיימים בהפעלה הנוכחית ויוצאים מהטווח כאשר היישום נסגר. אבל מה אם אתה רוצה לשמור על משתנים ספציפיים למשתמש לאורך הפעלות? באפשרותך לאחסן סוגי ערכים אלה בטבלה מקומית. ב- Northwind 2.0 משתנה אחד כזה נשמר בטבלה הנקראת SystemSettings. הערך בטבלה הוא ShowWelcome. ערך זה מציין אם ברצונך לראות את מסך הפתיחה בכל פעם שתיכנס או לא.

OpenArgs ו- StringFormat()

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

  1. הטופס השני יכול "להביט אחורה" לטופס הראשון כדי לקלוט כמה ערכים, אולי בפקד גלוי או בלתי נראה.  לדוגמה:
    lngCustomerID = Forms!FirstForm!cboCustomerID 
  2. הטופס הראשון יכול לשמור ערכים במשתנים כלליים או ב - TempVars. לדוגמה:
    g_lngUserID = Me.cboUserID 
    TempVars.Add "UserID", Me.cboUserID

השיטה המשמשת לעתים קרובות ב- Northwind Developer Edition כמו גם בחיינו המקצועיים היא שימוש בארגומנט OpenArgs של DoCmd.OpenForm או OpenReport. לדוגמה:

DoCmd.OpenForm "frmCompanyDetail", OpenArgs:=StringFormat("CompanyID={0} &CompanyTypeID={1}", Me.VendorID, ctVendor)

אנו משלבים כאן שתי טכניקות: (1) השימוש ב-OpenArgs כדי להעביר את VendorID ו-VendorType, ו-(2) השימוש בפונקציה StringFormat() כדי ליצור, למשל, את המחרוזת הזו:

CompanyID=5&CompanyTypeID=2 

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

name1=value1&name2=value2

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

בצד המקבל של DoCmd.OpenForm אנחנו בדרך כלל באירוע Form_Open או Form_Load ורוצים לנתח את מחרוזת OpenArgs לרכיבים שלה.

ב- Northwind, תוכל לעשות זאת עם הפונקציה StringToDictionary . הוא לוקח פונקציה דמוית-שאילתה ומנתח אותה לתוך הרכיבים שלה. רכיבים אלה מאוחסנים לאחר מכן באובייקט Scripting.Dictionary . שים לב שפעולה זו דורשת ממך להשתמש בהפניות כלים > ולהגדיר הפניה ל- Microsoft Scripting Runtime (scrrun.dll).

התכונות והיתרונות של אובייקט Dictionary כוללים את:

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

השימוש באובייקט המילון מופיע ברחבי Northwind. לדוגמה, האירוע Form_Load ב- frmGenericDialog.

טיפול בשגיאות

פקודות מאקרו שנוצרו באמצעות אשפי בקרה ב- Access כוללות לעתים רחוקות טיפול בשגיאות; VBA שנוצר באמצעות אשפי בקרה עשוי להיות מוגבל ל- MsgBox Err.Description כללי.

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

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

המאקרו AutoExec קורא לפונקציה Startup ב- modStartup. במהדורת Starter, הפונקציה יוצרת מופע של clsErrorHandler ושומרת אותו כמשתנה כללי הזמין לשימוש בכל היישום. במהדורת Dev נעשה שימוש במחלקה סטטית - עיין בהערות בחלק העליון של מודול המחלקה.

למעשה, קוד הטיפול בשגיאות בפרוצדורות הוא כל כך עקבי שהצלחנו ליצור את כולו בפחות מחמש דקות באמצעות קוד VBA ספציפי שצייד כל פרוצדורה במטפל השגיאות המתאים. (קוד לא כלול בתבנית). גם מהדורת התבנית Northwind 2.0 Starter וגם מהדורת התבנית Developer צוידו בתחילה בגישת טיפול בשגיאות זו. 
'

טיפול משופר בשגיאות

החל מגירסה 2.2 של Northwind Developer Edition, המטפל בשגיאות השתפר, הודות למשוב שהתקבל מקהילת Access. מהדורת Starter נותרה ללא שינוי. 

בעיקרו של דבר, המטפל בשגיאות בגירסה הקודמת (2.0 - שהופצה באפריל 2023) הוא:

Public Sub HandleError(…)
    MsgBox Err.Description
End Sub

בגירסה 2.2 הוא משודרג ל:

Public Sub HandleError (…, Optional ByVal IsEventProcedure As Boolean = False)
    If Not IsEventProcedure Then
        Err.Raise lngError, strErrSource
    End If
    MsgBox Err.Description
End Sub

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

  • המאקרו AutoExec מבצע קריאה לפרוצדורת האתחול, אשר מבצעת כמה אתחולים לפני פתיחת הטופס הראשון.
  • המשתמש מקיים אינטראקציה עם היישום, כגון פתיחת טופס או לחיצה על לחצן, וגורם לפרוצדורות אירוע לפעול כגון Form_Load ו - cmdPrintInvoice_Click.
    '

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

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

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

כדי להשתמש בקוד של Northwind בגירסה 2.2, פרוצדורות אירוע חייבות להעביר ל- HandleError ארגומנט שלישי המציין כי הקורא הוא פרוצדורת אירוע. Northwind Dev Edition עודכנה לעשות זאת.

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

רשימת MRU

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

במהדורת Northwind Dev, כדי ליישם את תכונת MRU (שאינה קיימת במהדורת Starter) עליך ליצור תחילה את הפריטים הבאים:

  1. טבלה לאחסון מידע MRU.
  2. קוד לעדכון הטבלה בעת פתיחת הזמנה או הזמנת רכש (PO).
  3. קוד לעדכון הרשימה הנפתחת MRU ברצועת הכלים.
  4. קוד לטעינת הפריט כאשר פריט MRU נבחר מרצועת הכלים.

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

1. טבלה לאחסון מידע MRU.

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

הטבלה מנצלת את העובדה שכל שדות ה- PK (מפתח ראשי) הקשורים ל- MRU במסד הנתונים הם בעלי מספור אוטומטי, כך שניתן להשתמש בסוג הנתונים 'מספר שלם ארוך' עבור PKValue.

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

ב-NW2 בחרנו להוסיף לרשימת MRU רק כאשר נוצרה רשומה חדשה, לא כאשר רשומה קיימת עודכנה שוב. אנחנו בהחלט יכולים להעביר את שיחת AddToMRUמ-Form_AfterInsertל-Form_AfterUpdate כדי לתמוך בזה.

הנהלים AddToMRUו-DeleteFromMRU מיושמים ב-modGlobal, שהוא מודול Standard שהנהלים הציבוריים שלו נראים מכל צורה.

AddToMRU (כפי שהשם מרמז) מוסיף את הפריט החדש לטבלת ה- MRU, ולאחר מכן באופן אופציונלי חותך אותו בחזרה, ומוחק את הרשומה הישנה, אם היא גדלה מעבר לגודל המקסימלי (MAX_MRU_COUNT). השלב האחרון הוא ככל הנראה השלב הפחות מוכר למפתחי Access: יש לרענן את הרשימה הנפתחת של רצועת הכלים, וזה מתבצע על-ידי קריאה ל- InvalidateControl. זהו אות לרצועת הכלים להפעיל מחדש את תהליך האתחול. 

3. קוד לעדכון הרשימה הנפתחת של MRU ברצועת הכלים.

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


<group id="gCurrentStatus" label="MRU">
    <box id="bxMRU" boxStyle="vertical">
        <dropDown id="ddMRU"
                  getItemCount="ddMRU_GetItemCount"
                  getItemLabel="ddMRU_GetItemLabel"
                  getSelectedItemIndex="ddMRU_GetSelectedItemIndex"
                  getItemID="ddMRU_GetItemID"
                  onAction="ddMRU_OnAction"
                  screentip="Most Recently Used Objects">
        </dropDown>
    </box>
</group>

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

אם תבטל את הערת השורות של Debug.Print ב - modRibbonCallback ותפעיל מחדש את היישום, החלון המיידי יציג רצף כזה:


ddMRU_GetItemCount    ddMRU    6 
ddMRU_GetItemLabel    ddMRU    0      Order 60, Proseware, Inc.
ddMRU_GetItemID       ddMRU    0       2 
ddMRU_GetItemLabel    ddMRU    1      Order 62, Best For You Organics Company
ddMRU_GetItemID       ddMRU    1       4 
ddMRU_GetItemLabel    ddMRU    2      Order 63, Wide World Importers
ddMRU_GetItemID       ddMRU    2       5 
ddMRU_GetItemLabel    ddMRU    3      Order 66, Proseware, Inc.
ddMRU_GetItemID       ddMRU    3       8 
ddMRU_GetItemLabel    ddMRU    4      Order 67, Best For You Organics Company
ddMRU_GetItemID       ddMRU    4       9 
ddMRU_GetItemLabel    ddMRU    5      Order 68, Adatum Corporation
ddMRU_GetItemID       ddMRU    5       10 
ddMRU_GetSelectedItemIndex  ddMRU    0

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

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

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

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

בדומה לכל פריט אחר ברצועת הכלים, המאפיין OnAction ב- XML של רצועת הכלים מציין פונקציית callback שתשמש לביצוע הפעולה:


onAction="ddMRU_OnAction"

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

מידע נוסף