פונקציה לבדיקת האם מחרוזת מתחילה באנגלית – VBA (Access)

לפעמים צריך ליישר אוטומטית

שדה ב-VBA

לשם כך בניתי פונקציה שבודקת האם השדה מתחיל באנגלית

במידה וכן – ניישר אותו בהתאם.

Public Function StringStratInEnglish(str As String) As Boolean
 Dim first_char As String
 On Error Resume Next
 
 StringStratInEnglish = False
 
 If Len(str) = 0 Then GoTo ExitHere
 first_char = Mid(str, 1, 1)
 
 If (Asc(first_char) >= 65 And Asc(first_char) <= 90) Or _
 (Asc(first_char) >= 97 And Asc(first_char) <= 122) Then
 
 StringStratInEnglish = True
 End If
 
ExitHere:
 Exit Function
End Function

התקנה שקטה של Access Runtime

כאשר אתה מפיץ תוכנות מבוססות Access, עם Access runtime

ואתה אורז את זה להפצה, נניח עם Inno Setup או תוכנות דומות.

אתה מעוניין שההתקנה של Access Runtime תרוץ בלי שאלות למשתמש

בלי קשקושים, בלי "אני מקבל את ההסכם" וכו' כו'

לצורך כך צריך לבצע את הפעולות הבאות :

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

קובץ ההתקנה שיורד הוא למעשה Self-Extracting  שמכיל קבצים ותיקיות רבים.

אז דבר ראשון צריך אנחנו נחלץ את כל הקבצים לתיקיה , ואז כאשר יהיו לנו את קבצי ההתקנה עצמה של Access Runtime, רק אז נוכל להגדיר את ההתקנה השקטה (silent install).

החילוץ :

YourAccessRuntimeInstallFile /extract:YourFolder

ואז ניכנס לתיקיה שאליה חילצנו את הקבצים.

וניצור קובץ בשם config.xml  שיכיל את ה-XML הבא :

<Configuration Product="AccessRT"> 
<Display Level="Basic" CompletionNotice="Yes" SuppressModal="Yes" NoCancel="Yes" AcceptEula="Yes" /> 
<Logging Type="standard" Path="C:TEMP" Template="Microsoft_Access_2013_Runtime_Setup(*).log" /> 
<COMPANYNAME Value="Y" /> 
<Setting Id="SETUP_REBOOT" Value="Never" /> 
</Configuration>

אפשר למצוא הסבר מלא על כל הפרמטרים , וכל ה-nodes של ה-XML הזה בקישור הבא : http://technet.microsoft.com/en-us/library/cc179195(v=office.15).aspx

ואז מריצים את הקובץ setup שנמצא בתוך התיקיה שחילצנו  עם הפרמטר הבא :

setup.exe /config YourConfigFileFullPath.xml

וזהו… זה רץ בהתקנה שקטה.

 

אקסס – התמודדות עם תקלה 3211 – טבלה נעולה (Access VBA Error 3211 )

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

המצב שלי היה כזה : לטופס היה טופס משנה שמבוסס על טבלה זמנית

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

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

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

ואז , את השאילתת שיוצרת את הטבלה הזמנית – יש להחליף בשאילתא INSERT רגילה.

בצורה כזו, Access מאפשרת את כל הפעולות, גם דרך ADO Recordset וגם דרך שאילתות.

בהצלחה!

הצגת מונה רשומות בתוך טופס Access

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

ולא להשתמש במונה המובנה של אקסס

 

השיטה הכי פשוטה היא לעשות תיבת טקסט ובתוכה

=" Record  " & [CurrentRecord] & " From  " & Count(*)


אבל  הבעיה היא שהשיטה הזו מחזיקה מעמד רק עד שפותחים רשומה חדשה

ברגע שפותחים רשומה חדשה – מקבלים דברים מוזרים כמו "רשומה 7 מתוך 6" וכדומה.

 

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

 

 If Me.NewRecord Then
 Me.txtCounter.Value = "New Record ( " & DCount("[PolicyID]", "tblPolicies", "[linkID]='" & Nz(Me.linkID, "") & "'") & " Exists Records "
 
 Else
 Me.txtCounter.Value = "Record " & Me.CurrentRecord & " Of " & DCount("[PolicyID]", "tblPolicies", "[linkID]='" & Nz(Me.linkID, "") & "'")
 End If

כמובן שתשנו את ה-Dcount לטבלה הרלוונטית עבורכם.

 

מקור להרחבה ושיטות נוספות : http://www.fontstuff.com/mailbag/qaccess04.htm

 

שימוש ב-Web Control המובנה של Access (דפדפן) ב-VBA

בגירסאות האחרונות של Microsoft Access יש Web Control מובנה

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

ב-VBA הגישה היא כזו :

.YourWebControl.ControlSource = "=" & Chr(34) & file_name & Chr(34)

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

YourWebControl.ControlSource = "=""www.google.co.il""

העברת ADO RECORDSET אל מערך ב-VBA

קורה לפעמים שעדיף לרוץ על מערך בזיכרון מאשר על רקורדסט – זה הרבה הרבה יותר מהיר

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


Public Function RecordsetToArray(ByRef rs As Object) As Variant
    Dim tmp As Variant, cols_num As Integer, K As Integer, rows_num As Integer, J As Integer
    
    If Not (rs.EOF And rs.BOF) Then
    
        rs.MoveFirst
        cols_num = rs.fields.Count
        rows_num = rs.RecordCount
        
        ReDim tmp(rows_num, cols_num)
            
            J = 0
            Do While Not rs.EOF
                For K = 0 To cols_num - 1
                      tmp(J, K) = Nz(rs.fields(K).Value, "")
                Next K
                J = J + 1
                rs.MoveNext
            Loop
    
    Else
        tmp = Array("")
    
    End If
    
    RecordsetToArray = tmp
    
End Function




המתנה ב-ACCESS VBA באמצעות WINDOWS API

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

להלן קוד.

#If VBA7 Then
    Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
#Else
    Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If


Sub SleepVBA(ms As Integer)
'ms = milisecondes
Sleep ms
End Sub

פונקצית 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

בהצלחה!

איך לגרום לשורה במבט טבלאי של דוח Access להסתיר את עצמה ?

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

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

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

בהצלחה!

Credit : Yochai

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

מבוסס על פתרון של Allen Browne

בעיקרון – אין אפשרות מובנה
עוקפים זאת כך

1. פתח את דוח המשנה בתצוגת עיצוב.

2. בחלונית המיון וקיבוץ, הזן ביטוי שלא ישתנה,
לדוגמה:
= 1

3. ציין שאתה רוצה כותרת עליונה של קבוצה בביטוי זה.
Access מוסיף סעיף חדש לsubreport.
שים את הכותרות שאתה רוצה שיחזרו על עצמם בראש כל עמוד – כאן.

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

ומרגע זה – סיימת.
הכותרות חוזרות על עצמן בראש כל עמוד.