Excel VBA@簽名檔小工具
專案緣由
工程的進行中有各式各樣的報表,大多數皆需要人工進行簽名,不能用蓋章的方式替代,若工程查核時,日積月累的報表通通列出來,一次簽整本的就會簽到懷疑人生,竣工時還要好幾份副本,由此可見每天做報表還是很重要的,但工地大家都忙,沒有查核是不會乖乖做的。
因此,如果可以讓報表列印前,隨機從簽名檔資料夾中挑選一張,並在報表的指定位置隨機移動及調整大小貼上簽名檔,讓報表的呈現能有人工簽名的感覺,應該可以節省很多時間。
搭配報表的批次列印,更可以看出效果如何。
前期準備動作
要完成這項專案前,必須要先有簽名檔的PNG或JPG們。
可以先準備一張A4紙,開始用【黑筆】瘋狂簽名,每個簽名大小都要差不多,將成果掃描至電腦上,並用剪取工具或其他美工軟體進行簽名的截取及去背,我是用powerpoint自帶的去背效果處理。
處理完成的PNG圖檔要放進簽名檔VBA中的【Sig】資料夾,名稱不一定要有意義,程式會自己隨機找一個。
註解:PNG通常是指沒有背景的照片格式,如為JPG有可能會在貼上時把後面的格線遮住。
在列印報表的事件前先讀取該活頁簿中的Sig.txt檔案,依據當中的資訊去抓取簽名檔並貼上到報表的指定位置附近,隨機調整位置及大小。
Sig.txt:
(作用工作表)            假設工程施工查驗表
(Left)                            86.25
(Top)                            734.896911621094
(Width)                        109.5
(Height)                       46.0261421203613
(簽名檔資料夾)        G:\我的雲端硬碟\ExcelVBA\簽名檔VBA\Sig
操作步驟(影片+步驟拆解)
1.打開要放簽名檔的活頁簿
2.將Sig資料夾中的簽名檔放置於報表中的位置並調整好大小
3.打開簽名檔設定工具.xls
4.回到設定工具
5.點選"1.列出工作表"
6.選擇需要簽名的工作表,在C欄填上"Y"
7.點選按鈕"3.擷取簽名資訊"
此時Sig.txt已經被製作完畢並放置於要作用的活頁簿同層目錄
8.移動至要作用的活頁簿
9.進入EXCEL VBA編輯器 (快捷鍵為Alt+F11)
10.找到Microsoft Excel物件下的ThisWorkbook點選兩下
11.貼上以下程式碼
'程式作者:HankLin
'發表日期:20231009
'EMAIL:apple84026113@gmail.com
'著作權所有,請勿刪除姓名標示
Private Sub Workbook_BeforePrint(Cancel As Boolean)
Call ReadTextFileToArray
End Sub
Sub ReadTextFileToArray()
    Dim FilePath As String
    Dim FileContent() As String
    Dim FileLine As String
    Dim FileNumber As Integer
    Dim LineCount As Integer
    ' Get the path of the current workbook and construct the file path
    FilePath = ThisWorkbook.Path & "\" & "Sig.txt"
    ' Check if the file exists
    If Dir(FilePath) <> "" Then
        ' Open the file and read content into an array
        FileNumber = FreeFile
        Open FilePath For Input As FileNumber
        ' Initialize the array
        ReDim FileContent(1 To 1) As String
        LineCount = 1
        Do While Not EOF(FileNumber)
            Line Input #FileNumber, FileLine
            FileContent(LineCount) = FileLine
            ReDim Preserve FileContent(1 To UBound(FileContent) + 1) As String
            LineCount = LineCount + 1
        Loop
        Close FileNumber
        ' Remove the last empty element
        ReDim Preserve FileContent(1 To UBound(FileContent) - 1) As String
        ' Display the file content in the worksheet
        Dim i As Integer
        For i = 1 To UBound(FileContent)
            If FileContent(i) <> "" Then
                Debug.Print FileContent(i)
                cnt = cnt + 1
                Select Case cnt
                Case 1: shtName = FileContent(i)
                Case 2: sigleft = FileContent(i)
                Case 3: sigtop = FileContent(i)
                Case 4: sigwidth = FileContent(i)
                Case 5: sigheight = FileContent(i)
                Case 6
                    sig_fd = FileContent(i)
                    photo_name = ListImageFileNamesToCollection(sig_fd)
                    If ActiveSheet.Name = shtName Then
                        Set pics = Sheets(shtName).Pictures
                        pics.Delete
                        Set pic = pics.Insert(sig_fd & "\" & photo_name)
                        pic.Left = sigleft + Rnd() * 20
                        pic.Top = sigtop + Rnd()
                        pic.Width = sigwidth - Rnd() * 2
                        pic.Height = sigheight - Rnd() * 2
                        End
                    End If
                End Select
            End If
        Next i
    Else
    End If
End Sub
Function ListImageFileNamesToCollection(ByVal FolderPath As String)
    Dim FileName As String
    Dim FileType As String
    Dim FileCollection As New Collection
    ' Get all files in the folder
    FileName = Dir(FolderPath & "\*.*", vbNormal)
    ' Iterate through the files in the folder
    Do While FileName <> ""
        FileType = LCase(Right(FileName, Len(FileName) - InStrRev(FileName, ".")))
        ' Check if the file type is an image type (you can add other image types as needed)
        If FileType = "jpg" Or FileType = "jpeg" Or FileType = "png" Or FileType = "gif" Then
            FileCollection.Add FileName ' Add the file name to the collection
        End If
        FileName = Dir
    Loop
    Randomize
    myIndex = Int(Rnd() * FileCollection.Count) + 1
    ListImageFileNamesToCollection = FileCollection.Item(myIndex)
End Function
檔案連結
*研討會分享*
如果對VBA在設計/監造的應用上有興趣
可以訂閱我的LINE通知或加入LINE社群
11月3日下午預計在高雄辦理一場研討會(實體、線上併行)
題目為【VBA在設計/監造階段的應用範例】
屆時將同步發送線上會議連結給有訂閱LINE通知的朋友
更多資訊連結
LINE社群  (工程人的設計監造VBA工具交流區)
LINE通知  (Hank'sVBA_公告服務)
LINE官方  (Hank'sVBA)
ID搜尋:@903qzhwa
 
Thank you for the authenticity and sincerity that shine through in your writing.
回覆刪除