איך להשתמש במתודה recalculateFormulas של המחלקה Formula כדי לעדכן ערכי שדות נוסחה בזמן ריצה

ליאור נכתב על ידי ליאור לביא, עודכן בתאריך 18/11/2023

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

דוגמה

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

Account shire = new Account(Name = 'The Shire', Site='Middle-Earth');
insert shire;

Contact bilboBaggins = new Contact(email = 'bbaggins@shire.com', firstName='Bilbo', lastName='Baggins', AccountId=shire.id);

System.debug('Account Site BEFORE Recalculation: ' + bilboBaggins.Account_Site__c); //Will output 'Account Site BEFORE Recalculation: null'

Formula.recalculateFormulas(new List<Contact>{bilboBaggins});

System.debug('Account Site AFTER Recalculation: ' + bilboBaggins.Account_Site__c); //Will output 'Account Site AFTER Recalculation: Middle-Earth'

הסבר

בדוגמה למעלה ביצענו את השלבים הבאים:

  1. יצרנו שדה נוסחה חדש דרך ה-UI בשם Account Site על האובייקט Contact והערך שהוא מציג הוא את ה-Site של ה-Account מהשדה Account על האובייקט Contact. Account Site Formula
  2. בקוד, יצרנו Account חדש עם השדה Name שווה ל-The Shire והשדה Site שווה ל-Middle-Earth וביצענו עבורו Insert ל-Database.
    Account shire = new Account(Name = 'The Shire', Site='Middle-Earth');
    insert shire;
  3. יצרנו רשומת Contact מבלי להזין אותה ל-Database.
    Contact bilboBaggins = new Contact(email = 'bbaggins@shire.com', firstName='Bilbo', lastName='Baggins', AccountId=shire.id);
  4. בנקודה הזאת הדברים מתחילים להיות מעניינים! בשורה 6 הרצנו את הפקודה System.debug כדי להדפיס את הערך ששדה הנוסחה Account Site מחזיר. כפי שאפשר לראות, הערך המוחזר הוא Null, וזאת למרות שאכלסנו את השדה AccountId על ה-Contact שלנו ב-Account שיש לו ערך בשדה Site, והוא Middle-Earth.
    System.debug('Account Site BEFORE Recalculation: ' + bilboBaggins.Account_Site__c); //Will output 'Account Site BEFORE Recalculation: null'
  5. בשורה 8 הרצנו את המתודה הסטטית Formula.recalculateFormulas והעברנו לה רשימה חדשה של רשומות SObject, במקרה שלנו Contacts, עם פריט אחד בתוכה, ה-Contact שיצרנו עבור Bilbo Baggins. המתודה recalculateFormulas מקבלת כארגומנטים Lists של SObjects, ו-Contact הוא Sub-Class של SObject.
    Formula.recalculateFormulas(new List<Contact>{bilboBaggins});
  6. בשורה 10 הרצנו את המתודה System.debug פעם נוספת, והפעם אכן קיבלנו חזרה את הערך Middle-Earth, משום שערך שדה הנוסחה חושב מחדש בהתאם לערך השדה AccountId.
    System.debug('Account Site AFTER Recalculation: ' + bilboBaggins.Account_Site__c); //Will output 'Account Site AFTER Recalculation: Middle-Earth'

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