עזרה | הזנת ערך הפרמטר באקסס
-
למה זה קורה
כתבתי ביטוי בבונה, זה הביטוי:CostPerProduct: vb_AveragePerMonthlyProduct(vb0MN(),[IDLtem])*[SealsCM]
כמובן כל השדות קיימים הכל כתוב נכון (ככל מה שידוע לי)
ראוי לציין ששדה SealsCM הוא שדה מחושב באותה השאילתה
תכלס בהפעלת השאילתה הוא מקפיץ חלון כזה
לאחר שאני לוחץ אישור (בלי לכתוב כלום בפנים)
אני מקבל את השדה מחושב בדיוק לפי מה שכתבתי בביטוימישהו יודע למה קופץ החלון הזה?
ומה אני צריך לכתוב כדי שלא יקפוץ? -
@אוריי אמר בעזרה | הזנת ערך הפרמטר באקסס:
לצערי גם כך לא עובד
לא נראה שיש סיבה שהסוגריים יעזרו משהו.
בעיה מוכרת.
אם השדה המחושב לא מסובך, תכניס אותו גם כאן במקום להפנות לשדה.
או שתפעיל שאילתה על השאילתה.אולי @clickone יש לו יותר מידע מתי זה קורה.
-
@מלא אמר בעזרה | הזנת ערך הפרמטר באקסס:
@אוריי אמר בעזרה | הזנת ערך הפרמטר באקסס:
לצערי גם כך לא עובד
לא נראה שיש סיבה שהסוגריים יעזרו משהו.
בעיה מוכרת.
אם השדה המחושב לא מסובך, תכניס אותו גם כאן במקום להפנות לשדה.
או שתפעיל שאילתה על השאילתה.אולי @clickone יש לו יותר מידע מתי זה קורה.
ככל הנראה זה מה שאני יעשה אבל זה לוקח הרבה משאבים לאקסס
בכל אופן שאילתה על שאילתה זה מה ש @clickone הציע לי אבל זה לא יותר קצר מלעשות את החישוב גם בחדש -
יש דרך ארוכה וקצרה ויש קצרה וארוכה:
הדרך הקצרה והארוכה
היא להכניס פונקציות שלך בתוך השאילתות ו...
א. להשתמש בשאילתת ביניים כמו ש @clickone ציין,
או
ב. להכפיל את החישוב גם עבור שדה זה (רח"ל) כמו ש @מלא ציין.
שתי הדרכים לא מומלצות, כמו שאסביר מיד.הדרך הארוכה והקצרה
ברגע שיש לי רעיון, הפיתוי הראשון שלי כמתכנת זה להתחיל מיד לכתוב קוד. אבל זה לא נכון.
הדרך הנכונה היא להשקיע זמן בתכנון נכון של מבנה הנתונים והשאילתות, בזרימה הרצויה של התוכנה, מה הקלט והפלט הרצוי וכו'. זה לוקח זמן, לפעמים מורט עצבים ומתסכל, אבל תמיד זה עדיף לעשות כן לפני שכתבתי שורת קוד אחת מאשר אחרי כן. עם הניסיון התהליך הזה נהיה יותר נעים וקצר.כללי אצבע:
- חישובים שאמורים להתבצע רק פעם אחת - לבצע רק פעם אחת ולשמור בטבלה.
- להמנע כמה שניתן מלהכניס פונקציות בשאילתות. בפרט פונקציות שמוגדרות על ידי המשתמש.
זה נכון הן מבחינת יעילות:
- שאילתות רצות הרבה יותר מהר מקוד VBA באקסס, כי כל קריאה לפונקציה דורשת משאבים מהמערכת.
- אתה לא צריך לחשב חישובים מיותרים פעמיים (או יותר) כדי שהשאילתא תואיל בטובה לקבל את הערך של הפונקציה.
- שים לב שאפילו בפונקציות טריוויאליות, כמו Nz() או IsNull() עדיף לרשום בSQL טהור ולא לבצע קריאה ל-VBA, תשווה למשל בין:
IsNull(SomeField) AS ValueIsEmpty
ל:
(SomeField Is Null) AS ValueIsEmpty
הראשונה קוראת לפונקצית VBA בשם IsNull() בעוד השניה משתמשת רק בSQL והיא הרבה יותר מהירה.
דוגמה שניה:
תשווה בין:Nz(Amount,0)
ל:
IIf(Amount Is Null, 0, Amount)
האופציה השנייה עדיפה בהרבה, כי היא משתמשת ב SQL טהור, ולכן
- אתה לא מבצע קריאה לפונקציה
- אתה שומר על טיפוס המשתנה בשדה (Data Type)
- הקריטריון (אם יש בשאילתה) מחושב נכון
- העמודה ממויינת נכון
(הערה: יש הבדל עצום בין IIF של SQL שהיא פונקציה יעילה, לבין IIF של VBA, שהוא פונקציה גרועה שמחשבת תמיד את שתי התוצאות האפשריות!)
והן מבחינת תחזוקה:
- לפעמים פונקציה כתובה לא נכון ומייצרת שגיאת ריצה שמוכפלת אלפי פעמים בשאילתא - תרחיש לא נעים בכלל הן לך כמפתח וכ"ש למשתמש.
- אם תרצה אי פעם לשדרג לבסיס נתונים אחר - הפונקציות לא יעבדו.
-
@www אמר בעזרה | הזנת ערך הפרמטר באקסס:
מה ההסבר בזה? למה זה נצרך? הרי ב 90% מהמקרים זה לא נצרך, מה הסברא לעשות ברירת מחדל כזה?
בכל פונקציה "רגילה" זה קורה.
באופן כללי, כשמספקים לפונקציה כלשהי פרמטרים שאינם משתנים "טהורים", אלא חישובים, החישוב של שני הפרמטרים מבוצע לפני ההשמה לפונקציה.
לדוגמא:Debug.Print MyMax(2, SquareRoot(2))
התוכנה תחשב גם את השורש הריבועי של 2, עוד לפני הקריאה לפונקציה MyMax, למרות שבסוף לא תשתמש בו.
היתרון ב-IIF של SQL הוא שאם התנאי נכון, לא מבוצע חישוב של הפרמטר השני, והשאילתא מתעלמת ממנו.
הניחוש שלי הוא שב-VBA הפונקציה IIF מיושמת כפונקציה רגילה ולא כקיצור ל IF שלם, דהיינו:IIF (Condition, A, B)
אינו מיושם כ:
If (Condition) Then Do A Else Do B End If
-
@odeddvir אמר בעזרה | הזנת ערך הפרמטר באקסס:
התוכנה תחשב גם את השורש הריבועי של 2, עוד לפני הקריאה לפונקציה MyMax, למרות שבסוף לא תשתמש בו.
מי גילה למחשב (לפני החישוב של הפרמטר השני) שבסוף לא אשתמש בו?
משא"כ ב IIF יש הסתברות (ממוצעת) של 50% שלא אשתמש בתנאי השני.טוב כנראה שהתשובה היא שהפלטפורמה מיושנת וכמו שכתבת שכל פונקציה רגילה פועלת כך שקודם מבוצע הקריאה לערך העמוק ביותר, אז גם כאן זה ככה.