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

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

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

פונקציה זו נועדה לחשב דברים באמצעות אקסל
יש לספק 3 פרמטרים:
1. שם הקובץ
2. מערך המכיל את המידע שיש לשתול באקסל
3. מערך המכיל את התאים שיש לקבל מאקסל
הפונקציה שותלת את המערך מהפרמטר השני
ואז ממלאת את המערך מהפרמטר השלישי ומחזירה אותו
כלומר תוצאה הפונקציה היא מערך!
במקרה של תקלה – תוצאה הפונקציה תהיה בוליאנית – שקר

מבנה המערכים –
שתי המערכים באותו מבנה – דו מימדי, כאשר תיאור העמודות נשמר ב
ENUM = E_XL_DataAry

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

הערה : הפונקציה שמוזכרת פה IsArrayAllocated, היא פונקציה רק שבודקת האם זהו מערך תקין, ואינה מחויבת (היא לא חלק מ-VBA, אלא בנפרד).

Public Enum E_XL_DataAry
    
    SheetNameCol = 0
    CellAddressCol = 1
    ValueCol = 2

End Enum


Public Function CalculateByExcel(file_name As String, DataToPutAry As Variant, DataToGetAry As Variant) As Variant
    
    Dim xl As Object, wb As Object, ws As Object, I As Integer
    'open the xl
    Set xl = CreateObject("Excel.Application")
    xl.Visible = False
    Set wb = xl.Workbooks.Open(file_name, 2, True)
    
    If (Not IsArrayAllocated(DataToPutAry)) Or (Not IsArrayAllocated(DataToGetAry)) Then GoTo Err_Handel
    
    'Put Data into cells
    For I = LBound(DataToPutAry) To UBound(DataToPutAry)
            wb.Worksheets(DataToPutAry(I, E_XL_DataAry.SheetNameCol)).range(DataToPutAry(I, E_XL_DataAry.CellAddressCol)).Value = DataToPutAry(I, E_XL_DataAry.ValueCol)
    Next I
    
    For I = LBound(DataToGetAry) To UBound(DataToGetAry)
            DataToGetAry(I, E_XL_DataAry.ValueCol) = wb.Worksheets(DataToGetAry(I, E_XL_DataAry.SheetNameCol)).range(DataToGetAry(I, E_XL_DataAry.CellAddressCol)).Value
    Next I
     
    CalculateByExcel = DataToGetAry
     
    wb.Close False ' close the source workbook without saving any changes
    Set wb = Nothing
    xl.Quit
    Set xl = Nothing

Exit_Func:
    Exit Function


Err_Handel:
    CalculateByExcel = False
    Resume Exit_Func
    
End Function

דוגמא לשימוש פשוט – כאשר מוחזר רק תא אחד בודד


Sub TryIt()
Dim x As Variant, a As Variant, b As Variant
ReDim a(0, 3)
a(0, 0) = "Sheet1"
a(0, 1) = "A1"
a(0, 2) = "1"
ReDim b(0, 3)
b(0, 0) = "Sheet1"
b(0, 1) = "A2"


x = CalculateByExcel("YourXLFile.xlsx", a, b)
Debug.Print x(0, 2)

End Sub

ודוגמא לשימוש מורכב יותר, כאשר מוחזר טווח של 2 תאים לדוגמא


Dim x As Variant, a As Variant, b As Variant
ReDim a(0, 3)
a(0, 0) = "Sheet1"
a(0, 1) = "A1"
a(0, 2) = "1"
ReDim b(0, 3)
b(0, 0) = "Sheet1"
b(0, 1) = "A2:A3"


x = CalculateByExcel("YourXLFile.xlsx", a, b)
Debug.Print x(0, 2)(1,1)

End Sub

בהצלחה!

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *