2024/12/05

PowerShell / 使用筆記-如何將參數帶入.ps1檔

之前曾經在測試DLL的時候使用了PowerShell

最近剛好又翻到當時的測試檔

不過時間久了,如何執行.psl檔都沒印象了

2024/12/04

Excel / 如何使用VBA連線FTP 3

接下來要介紹winscp COM Library在excel vba的簡單使用方式

如果照抄範例,有修改連線主機跟帳密,程式還是會出錯的

2024/12/03

Excel / 如何使用VBA連線FTP 2

Excel / 如何使用VBA連線FTP 提供了2種透過windows內建ftp程式的連線方式

但是這可能會因為ftp伺服器的關係而無法使用

例如採取加密的ftp伺服器就會因為無法連線而不能夠使用

2024/11/08

Word / Label設定成button樣式效果

延續「Word / Command Button 無法設定文字對齊的替代方案,使用Label

因為 Label可以控制文字置中,所以用來替代Command Button

2024/11/07

Word / Command Button 無法設定文字對齊的替代方案,使用Label

在「Word / 使用VBA分割word內的表格」的按鈕

如果不特別設定的話,文字都會被遮蓋

也無法做任何的調整

爬文得到的解決方式

有人建議前後增加空格,或者調整字體或字型大小,因為當整體長度超過按鈕寬度就會自動置左

這種純手動,不是很方便

有人建議改用Label(標籤)

雖然少了按鈕的動態效果,但至少文字是可以完整呈現

所以我改用Label來綁定程式碼

這樣畫面感覺好多了!!

Excel / 使用VBA控制word物件來分割表格

之前在「Word / 使用VBA分割word內的表格」使用VBA分割表格

現在同樣的原因需要分割審查結果的表格

表格架構都一樣,要輸出的內容架構也一樣

這次改在excel控制word物件來分割word裡的表格

2024/11/03

Excel / 使用VBA批次修改檔案名稱

這個是Line社團的提問

讓我想起之前"彰化一整天"有個類似的VBA程式

2024/10/28

JS / 以Google Apps Script為中繼API,修改傳遞到blogger的草稿

之前「網站 / 從wordpress發佈新文章同步寄信到blogger儲存成草稿

在 wordpress網站建立觸發器,發布新文章的同時,直接將文章內容寄到blogger的自訂信箱作為草稿

2024/10/13

JS / 結合Google Apps Script製作API,自製hilite.me程式碼上色

hilite.me是一個程式碼上色的網站

2024/10/05

Gg / Google sheets CHOOSECOLS 函數─Excel CHOOSE函數的替代方法

在「Excel / VLOOKUP / LOOKUP函數 (2024/2/26 修改)
曾經提到 可以用CHOOSE函數重新建立一個參照範圍,配合資料情況設計取得唯一符合條件的資料

2024/10/04

Gg / Google Drive 移動副本文件到特定資料夾 6

除了「Gg / Google Drive 移動副本文件到特定資料夾 5」 
fetch網頁應用程式之外,還有另一種方式─把程式部署成「資料庫」(library) 

Gg / Google Drive 移動副本文件到特定資料夾 5

「Gg / Google Drive 移動副本文件到特定資料夾」系列主要內容都介紹差不多了
本篇想要紀錄如何從容器的文件使用onOpen觸發器執行另一個專案(非容器)的程式

2024/10/03

Gg / Google Drive 移動副本文件到特定資料夾 4

Gg / Google Drive 移動副本文件到特定資料夾 3」說明主程式
接下來說明子程式

Gg / Google Drive 移動副本文件到特定資料夾 3

接續「Gg / Google Drive 移動副本文件到特定資料夾 2
本篇說明主程式 getDatafromSheet()執行的內容

2024/10/02

Gg / Google Drive 移動副本文件到特定資料夾 2

延續「Gg / Google Drive 移動副本文件到特定資料夾 1
處理如何把上傳的檔案分門別類放在各自的資料夾內

Gg / Google Drive 移動副本文件到特定資料夾 1

辦完講師培訓,接下來是收檢核作業
為了方便起見,透過Google 表單上傳作業

2024/09/21

Excel / 使用SeleniumBasic查詢發布到網路的google sheets V2

同樣是抓取表單資料,Excel VBA 可以利用SeleniumBasic模擬操作瀏覽器抓取網頁資料

2024/09/20

Gg / 以Google sheets作為資料庫,透過Google Apps Script製作查詢頁面 修改版4 part2

2024/09/14

Gg / 以Google sheets作為資料庫,透過Google Apps Script製作查詢頁面 修改版4 part1

時間過得好快
這次的修改是要處理"資料還在增加的階段",而且"要把所有資料都集中在同一個工作簿"

2024/09/11

Excel / 如何刪除自訂的增益集

這個狀況是發生在之前測試Line社團的問題「VBA / Excel 使用VBA合併套印輸出並轉成PDF
發問者後來把Excel Vba轉存成增益集(副檔名 xlam)

2024/09/07

VBA / Excel 使用VBA取得word檔案內表格資料

由於辦理縣市薦派人員性質的研習
這種研習通常會設計制式表格給縣市承辦人填寫
而因為報名表格需要層層核章,再加上公文傳遞只能用pdf格式或者odf格式(odt文件)
所以通常會用odt文件來製作報名表,讓承辦人可以填寫並核章

2024/08/31

App / 使用App Inventor 製作取得公車到站時間的App 2

改良之前的「App / 使用App Inventor 製作取得公車到站時間的App
原來的版本是連結交通部運輸資料流通服務網站的API來抓取台北市公車資訊

2024/08/28

VBA / Excel 使用VBA分割工作表並另存新檔

這個練習其實是很久之前VBA的課程內容
透過VBA利用篩選的功能來分割工作表

2024/08/24

VBA / Excel 使用VBA合併套印輸出並轉成PDF

這個是在Line社團裡面的討論

有人發問想在word合併列印之後直接將檔案輸出成PDF

由於這是超過word本身的流程,因此只能透過VBA來達成

2024/07/21

安康接待室

請支援攝影 
所以去幫忙其他計畫的攝影工作

2024/06/09

Gg / 從Google Spreadsheets建立查詢ISBN的AppSheet APP 版本3

2024/05/27

VBA / Excel 使用VBA在Word檔內進行尋找取代的方法 2

VBA / Excel 使用VBA在Word檔內進行尋找取代的方法 說明了幾種處理方式 
但是如果要成為工作流程,必須要增加一些功能與介面以方便使用
所以增加清除內容、 選取檔案、執行搜尋替代等功能

2024/05/24

VBA / Excel 使用VBA在Word檔內進行尋找取代的方法

這個是在Line社群的問題
發問者自己也在網路上爬文,但是對於一些問題無法解決才來提問

2024/05/21

C# / Windows Powershell 與 Powershell的差異

最近在研究Powershell
發現有2種版本,也不能說是版本,應該是種類
一種是根植於Windows,以 .NET Framework v4.5為架構的Windows Powershell 5.1
另一種是從 .NET Framework 移至 .NET Core架構 的Powershell 7.X
這又要回過來認識.NET的種類

網站 / WordPress外掛Post Views for Jetpack無法更新瀏覽次數

這個外掛可以在首頁呈現Jetpack 外掛所統計的瀏覽次數
起始點是從安裝 Jetpack外掛之後
但是後來注意到首頁呈現的瀏覽數會停止更新

2024/05/15

JS / 在Blogger增加”文章行事曆”功能

嘗試在blogger新增文章行事曆
希望樣式類似triohobby網站

VBA / Excel VBA將檔案另存成PDF再使用自訂python程式加密PDF 番外

番外1-封裝執行檔被偵測有木馬程式

VBA / Excel VBA將檔案另存成PDF再使用自訂python程式加密PDF 系列文章
都是用pyinstaller將程式碼封裝成執行檔
不過在執行檔產生之後不久,Microsoft Defender 會顯示偵測到木馬程式

2024/05/03

VBA / Excel VBA將檔案另存成PDF再使用自訂python程式加密PDF 4

在前一篇 VBA / Excel VBA將檔案另存成PDF再使用自訂python程式加密PDF 3
曾經思考有沒有辦法不用先產生檔案的方式
轉了很多彎,後來看PyPDF2的說明

VBA / Excel VBA將檔案另存成PDF再使用自訂python程式加密PDF 3

再次修改 VBA / Excel VBA將檔案另存成PDF再使用自訂python程式加密PDF 的程式碼
1.使用 WScript.Shell 執行命令列、2.在迴圈增加 "DoEvents" 移交控制權
這次是修改python程式碼

2024/04/30

C# / Excel VBA將檔案另存成PDF再使用自訂C#程式加密PDF

本篇是 VBA / Excel VBA將檔案另存成PDF再使用自訂python程式加密PDF 的番外

在爬文的過程中,可能因為關鍵字的關係「 VBA PDF 加密」

所以跑出一篇在mobile01論壇的教學 使用vba + 開源函式庫,解決excel 另存pdf 無法加密問題(vba範例)

為了下載檔案而加入會員,還好檔案還在、還好不需要什麼鬼積分

依樣畫葫蘆可以得到相同結果

但是這個開源ProtectPDF.dll引起我的興趣

再次爬文之後,在這篇 VBA : encrypted / password protected PDF for MS Office

可以看到使用相同名稱的DLL

但是這篇文章的作者沒有提供ProtectPDF.dll檔案

下面有人問他 “Where is ProtectPDF.dll download site ” 也沒有得到回應

所以嘗試用dnSpy看看能不能反編譯在mobile01論壇下載的DLL,看看兩篇文章的DLL是不是一樣的

根據dnSpy的編譯結果,可以確認至少功能是一樣的

如同VBA : encrypted / password protected PDF for MS Office所提到的

這個DLL是用C#編寫的,主要是使用ITEXTSHARP.dll的功能

Rummaging through all the above to address the simple task of filling in a gap in the Word/Excel object model functionality to save an encrypted PDF and set different security options from VBA, I found that the simplest and quickest solution to make a custom COM wrapper around one of well-known .Net open source libraries. As an in house component, you shouldn’t have to worry about getting IT approval.

If you not familiar with making COM visible .NET DLL, here is an attached Visual Studio 2013 .NET v 4.0 project, written in C# and wrapping a popular library ITEXTSHARP.dll which is an .NET PDF library ported from Java.

For simplicity, ITEXTSHARP.dll is imbedded into single output resulting library ProtectPDF.dll with a single method 
GoPDF.ProtectPdfStandard(string passwordUser,  string passwordOwner, string namepathPDFIn, string namepathPDFOUT )

所以嘗試改成用exe來執行程式碼

基本上就是把ProtectPdfStandard()抓出來,在main()接收參數後執行

流程:

1.在visual studio新增C#解決方案

2.修改預設的Program.cs程式碼,也可以修改名稱,visual studio會自動修改相關的登錄設定

#3 引用 iTextSharp.text.pdf

#20-23 接收命令列傳來的參數

#29 將參數傳到 自訂函數ProtectPdfStandard

#39-81 ProtectPdfStandard的內容,都是從ProtectPdfStandard()抓來的

重點是在#61-70執行iTextSharp.text.pdf的PdfReader.Encrypt方法

Program.cs程式碼如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
using System;
using System.IO;
using iTextSharp.text.pdf;

namespace goPdf
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //Console.WriteLine($"parameter count = {args.Length}");
            /*
            for (int i = 0; i < args.Length; i++)
            {
              Console.WriteLine($"Arg[{i}] = [{args[i]}]");
            }*/
            if (args.Length > 0)
            {
                //
                string passwordUser = args[0];
                string passwordOwner = args[1];
                string inputPath = args[2];
                string outputPath = args[3];
                //Console.WriteLine(passwordUser);
                //Console.WriteLine(passwordOwner);
                //Console.WriteLine(inputPath);
                //Console.WriteLine(outputPath);
                //
                string errorText = ProtectPdfStandard(passwordUser, passwordOwner, inputPath, outputPath);
                Console.WriteLine(errorText);
                //
            }
            else
            {
                Console.WriteLine("沒有輸入參數");
            }
        }

        public static string ProtectPdfStandard(string passwordUser, string passwordOwner, string namepathPDFIn, string namepathPDFOUT)
        {
            string text = string.Empty;
            string result;
            if (string.IsNullOrWhiteSpace(passwordUser))
            {
                result = "Error: User Password not set";
            }
            else if (string.IsNullOrWhiteSpace(passwordOwner))
            {
                result = "Error: Owner Password not set";
            }
            else if (string.IsNullOrWhiteSpace(namepathPDFIn))
            {
                result = "Error: User Password not set";
            }
            else if (string.IsNullOrWhiteSpace(namepathPDFOUT))
            {
                result = "Error: Owner Password not set";
            }
            else
            {
                try
                {
                    using (Stream stream = new FileStream(namepathPDFIn, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        using (Stream stream2 = new FileStream(namepathPDFOUT, FileMode.Create, FileAccess.Write, FileShare.None))
                        {
                            PdfReader pdfReader = new PdfReader(stream);
                            PdfEncryptor.Encrypt(pdfReader, stream2, true, passwordUser, passwordOwner, 2564);
                        }
                    }
                }
                catch (Exception ex)
                {
                    text = ex.Message;
                }
                result = text;
            }
            return result;
        }

    }
}

3.在參考引用ITEXTSHARP.dll

備註:ITEXTSHARP.dll是從dnSpy另存出來的

4.測試或者建置,在bin資料夾的Debug資料夾內會產生exe檔跟相關的檔案,包含參考的ITEXTSHARP.dll

5.在Excel VBA內執行

這邊的流程就大同小異,不過因為這個函數接收4個參數

passwordUser 開啟密碼
passwordOwner 編輯權限密碼
inputPath 輸入檔案路徑
outputPath 輸出檔案路徑

所以程式碼稍微修改如下

#42-57 新增了一個陣列,用來存儲輸出的檔案路徑

#72-75 設定參數,密碼的部分之後可以再視情框修改

#78 執行命令列

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
Public Sub tt3()

    Application.DisplayAlerts = False
    Application.ScreenUpdating = False
    
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    ActiveWorkbook.Sheets(1).Activate
    
    '目前檔案路徑
    nPath = ActiveWorkbook.Path
    '輸出資料夾名稱
    strFolderName = "output"
    
    '完整的輸出資料夾路徑
    outputFolderPath = nPath & Application.PathSeparator & strFolderName & Application.PathSeparator

    '判斷輸出資料夾是否存在
    strFolderExists = Dir(nPath & Application.PathSeparator & strFolderName, vbDirectory)
    
    If strFolderExists = "" Then
        '不存在則新增
        fso.CreateFolder nPath & Application.PathSeparator & strFolderName
    Else
        '存在則移除 再新增
        fso.DeleteFolder nPath & Application.PathSeparator & strFolderName, True 'True 強制刪除
        fso.CreateFolder nPath & Application.PathSeparator & strFolderName
    End If
    
    '將工作表轉存為PDF檔
    For i = 2 To Sheets.Count
        nName = Sheets(i).Name
        Sheets(i).Copy
        ActiveWorkbook.ExportAsFixedFormat Type:=xlTypePDF, Filename:=outputFolderPath & nName & ".pdf"
        ActiveWorkbook.Close False
    Next
    
    '讀取output資料夾的PDF 如果存在 回傳檔案名稱.副檔名
    pdfFile = Dir(outputFolderPath & "*.pdf")
        
    Dim fileArr() As String
    Dim outArr() As String
    
    i = 0
    Do While pdfFile <> ""
        ReDim Preserve fileArr(i)
        ReDim Preserve outArr(i)
        fileArr(i) = outputFolderPath & pdfFile
        'Debug.Print outputFolderPath & pdfFile
        
        outArr(i) = outputFolderPath & Split(pdfFile, ".")(0) & "_PW.pdf"
        'Debug.Print outputFolderPath & Split(pdfFile, ".")(0) & "_PW.pdf"
        
        i = i + 1
        pdfFile = Dir()
    Loop
        
    'Debug.Print fileArr(0)
    '陣列上限(序位值)
    num = UBound(fileArr)
    
    Dim wsh As Object
    Set wsh = VBA.CreateObject("WScript.Shell")
    Dim waitOnReturn As Boolean: waitOnReturn = True
    Dim windowStyle As Integer: windowStyle = 0
    Dim errorCode As Long
    
    For i = 0 To num
            
        DoEvents
        passwordUser = "123"
        passwordOwner = "456"
        inputPath = fileArr(i)
        outputPath = outArr(i)
        
        '透過WScript.Shell 執行pdf加密程式
        s = Chr(34) & Excel.ActiveWorkbook.Path & "\C#\goPDF\" & "goPDF.exe" & Chr(34) & Chr(32) & Chr(34) & passwordUser & Chr(34) & Chr(32) & Chr(34) & passwordOwner & Chr(34) & Chr(32) & Chr(34) & inputPath & Chr(34) & Chr(32) & Chr(34) & outputPath & Chr(34)
            
'        Debug.Print s
        Shell s

        errorCode = wsh.Run(s, windowStyle, waitOnReturn)

        If errorCode = 0 Then
'            MsgBox "Done! No error to report."
            Debug.Print "輸出:" & fileArr(i) & Chr(32) & "到:" & outArr(i)
        Else
            MsgBox "Program exited with error code " & errorCode & "."
        End If
    Next
    
    Application.DisplayAlerts = True
    Application.ScreenUpdating = True
End Sub

 

參考資源

使用vba + 開源函式庫,解決excel 另存pdf 無法加密問題(vba範例)

VBA : encrypted / password protected PDF for MS Office

VBA / Excel VBA將檔案另存成PDF再使用自訂python程式加密PDF 2

本篇主要修改 VBA / Excel VBA將檔案另存成PDF再使用自訂python程式加密PDF的程式碼
讓程式執行更為流暢
主要修改的地方有以下兩點

2024/04/27

VBA / Excel VBA將檔案另存成PDF再使用自訂python程式加密PDF

VBA能否將excel轉成加密的PDF?

這個是在Line的excel社團看到的提問

其中的管理員提供了一個網路教學

這個教學是使用 Adobe Acrobat 物件

但是前提是必須先安裝付費版的 Adobe Acrobat

我後來想起之前彰化一整天有分享某個客製程式

其中有PDF加密功能,這個功能是在VBA執行他自己寫的python程式

經過自己土炮測試之後

2024/04/20

JS / 在Blogger增加”goTop”功能

在很多網站都能夠看到

當瀏覽到頁面結尾時,會出現一個回到最上面的圖示

點擊之後,網頁就會捲到最上面 在 tricohobby也有,這是佈景主題內建的

不過在blogger就要自己土炮

2024/04/15

Gg / 使用GoogleCharts快速製作QrCode 替代方案 QuickChart

原本在 Gg / 使用GoogleCharts快速製作QrCode 所使用的api

由於google正式關閉了 https://chart.googleapis.com

所以也就無法用來生成Qr Code

2024/04/14

Py / 透過selenium-webdriver爬youtube的介紹資訊 2

Py / 透過selenium-webdriver爬youtube的介紹資訊(2021/10/28修改)

所引用的selenium-webdriver 在更新之後,目前selenium版本是4.19.0

網站 / 使用Google Translate JS將網站變成多語系網站

聽說網站如果能夠具備多語系內容 

可以更容易被搜尋到 

但是我又不會多語

2024/03/23

網站 / 改善wordpress網站的效能

之前網站因為增加了許多自訂的發文推播

導致網站速度變慢,GCP的VM觀測數據顯示發文的時候,CPU的執行率可以達到200%

所以也出現提升CPU等級的建議,但是往上升一級就多了近一倍的費用

對我來說實在吃不消,因為除了GCP的費用之外,還有youtube的月費、google 雲端硬碟的年費

一年付給google公司7~8千元跑不掉,GCP費用占了80%

當初建置網站的目的是為了紀錄一些學習程式的過程,順便紀錄自己感興趣的東西

所以想先試試看能不能透過一些方式來降低網站的執行負荷量

2024/03/18

VBA / 使用Excel VBA批次寄信 3

之前在VBA / 使用Excel VBA批次寄信 是修改 彰化一整天所寫的excel VBA程式
而這個版本是精簡程式,原理是一樣的,都是使用 CDO.Message物件
但是省去了設定頁面,呈現核心程式
只要知道STMP的設定資料
各個郵件伺服器應該都可以使用
本文以Gmail為範例

2024/03/15

JS / 在Blogger增加”分享到臉書”功能

之前在網站 / 從wordpress發佈新文章同步發文到臉書粉絲專頁提到
臉書只能夠用分享的方式將訊息貼到個人頁面
於是,開始思考如何在Blogger達成這個效果

2024/03/14

JS / 移除或修改 iframe的屬性

前幾天辦公室裡其他計畫的助理
抱怨網站嵌入的google表單出現

「您的瀏覽器尚未啟用javascript...」

2024/03/08

網站 / 從wordpress發佈新文章同步發文到臉書粉絲專頁

既然可以透過寄信到Blogger發文 
那有沒有可能在臉書粉絲專頁貼文?

2024/03/05

網站 / 從wordpress發佈新文章同步寄信到blogger儲存成草稿

google blogger可以接收電子郵件來發佈文章

2024/03/02

JS / 在Blogger增加”修改”連結標籤

Blogger 修改文章必須到後台文章列表按指定文章  
 不像wordpress登入之後文章列表自動會有"Edit"的連接標籤  因此嘗試在文章列表增加文章修改的連結標籤 
 Blogger的文章修改連結的架構是 https://www.blogger.com/blog/post/edit/blogID/postID 所以需要1.取得postID、2.新增標籤 而根據取得postID的方式可以再分成2種方式

2024/02/29

JS / 在Blogger建立分頁

Blogger沒有辦法用增加<!--nextpage-->的方式在文章內設定分頁

2024/02/27

Gg / 透過Google Apps Script 建立上傳檔案頁面

這個使用Google Apps Script 建立的上傳檔案頁面,參考很多範例跟參考資源 
也因為需求而修改、新增功能,例如將檔案資訊呈現在頁面上、限制上傳者、特定檔案格式與檔案大小、可以同時多個檔案上傳 
不過詳細參考哪些內容,已經不可考了 
唯一能確認的是有參考《Google Apps Script雲端自動化與動態網頁實戰》的範例,這本書也是目前正體中文唯一的相關書籍 
整體而言,都是使用Google的相關功能:
以google雲端硬碟為儲存空間,並且將檔案資訊紀錄在google 試算表,呈現在Google Apps Script網頁程式建構的網頁   
 

2024/02/24

App / 使用App Inventor 製作取得公車到站時間的App

這個App單純是懶得在台灣等公車多按幾下 想直接秀出下班要搭的278公車到站時間

2024/01/11

VBA / Excel VBA 播放音檔

這個是臉書社群的問題

2024/01/08

VBA / 使用Excel VBA插入圖檔

這個是在Line Excel VBA社群的問題 發問者提供了操作影片跟檔案,所以可以很好理解所遇到的問題
  
 原始檔案利用VBA寫了兩個程序   檔案一開始就存在的圖檔可以刪除 後來新增的圖檔卻不能刪除 研究了一下

發現這是圖檔類型(MsoShapeType)的問題

程式碼是利用 Sheet.Pictures.Insert()方法插入的圖片 圖檔類型是msoLinkedPicture 但是檔案一開始就存在的圖片應該是在工作表透過插入/圖片的方式 這樣圖檔類型會是msoPicture 從名稱就可以看出差別 前者是連結圖檔而已,所以當圖檔改變名稱或位置時 工作表就會讀不到圖檔

單就無法刪除圖檔的問題,只需要多一個條件就可以了

原始程式碼只有判別 msoPicture
1
2
3
For Each a In ActiveSheet.Shapes
        If a.Type = msoPicture Then a.Delete
Next
  增加另一個 msoLinkedPicture的條件
1
2
3
For Each a In ActiveSheet.Shapes
        If a.Type = msoPicture Or a.Type = msoLinkedPicture Then a.Delete
Next
 

但是比較好的方式是將匯入程式碼改為利用 Sheet.Shapes.AddPicture()

AddPicture (FileName、 LinkToFile SaveWithDocument、 Left、 Top、 Width、 Height) 而且這個方式也可以在參數設定時,設定成以連結方式讀取圖檔 原始程式碼 工作表的B欄儲存檔案名稱,而圖檔跟工作簿是放在同一個資料夾內
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
With Sheets("清冊")
	lRow = .[b65536].End(xlUp).Row
	For I = 2 To lRow
	On Error Resume Next
		'strFile = ThisWorkbook.Path & "\" & .Cells(i, 4) & ".jpg"
		strFile = ActiveWorkbook.Path & "\" & .Cells(I, 2) & ".jpg"
		Set oPic = .Pictures.Insert(strFile)
		With .Cells(I, 3)
			oPic.Top = .Top
			oPic.Left = .Left
			oPic.Width = 60
			oPic.Height = 70
		End With
		Set oPic = Nothing
	Next I
End With
  修改後的程式碼
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
With Sheets("清冊")
        lRow = .[b65536].End(xlUp).Row
        For I = 2 To lRow
        On Error Resume Next
            'strFile = ThisWorkbook.Path & "\" & .Cells(i, 4) & ".jpg"
'            strFile = "C:\Users\trico\Pictures" & "\" & .Cells(I, 2) & ".jpg"
            strFile = ActiveWorkbook.Path & "\" & .Cells(I, 2) & ".jpg"
            Set oPic = .Shapes.AddPicture(strFile, msoFalse, msoTrue, Cells(I, 3).Left + 2, Cells(I, 3).Top + 1, 120, 70)
            Set oPic = Nothing
        Next I
End With
  補充 當 LinkToFile 為msoFalse時, SaveWithDocument必須為msoTrue,插入的圖檔類型為 msoPicture 但是LinkToFile 為msoTrue時, SaveWithDocument無論是msoTrue或msoFalse,插入的圖檔類型都是 msoLinkedPicture

備註1

比較奇怪的點,同樣的圖片寬度設定,使用Shapes.AddPicture()插入的圖檔大小只有Pictures.Insert()的一半 所以在 Shapes.AddPicture()的寬度設定為Pictures.Insert()的2倍 (60→120) 不過後來發現在 Pictures.Insert()的寬度跟高度只要擇一設定就好了 現在的圖檔是會以高度等比例調整寬度,所以最終寬度其實不是60

備註2

Pictures.Insert()找不到官方的說明資料 找到的都是教學類或者論壇的使用範例 vba插入圖片問題 VBA help for a Macro (inserting picture from file)