やること
EXCELで外部toolを呼び出し結果を取り込む際のメモをまとめておく。
事前確認:Qiitaでの記事
ということで、以下の検索をしたところ、154件ヒットした。(2025/01/30時点)
「VBAでPythonを動かす」の検索結果 - Qiita
以下、ご紹介。(検索結果以外を1つ含む)
(参考)Run と Exec の違い
いきなり検索結果以外で、Qiiraの記事ではない話。
「Exec メソッド」。「Run メソッド」、「xlwings」辺りがでるかと想像し、以下を紹介しておきます。
Run と Exec の違い【WSH】 | バグ取りの日々
投稿 2018/06/06 更新 2023/03/14
Exec メソッド
VBAでPythonを動かす #Excel - Qiita
投稿日 2020年02月22日
Run メソッド
あると思ったのですが……。
xlwings
VBAユーザーのためのPython入門 ~xlwingsでExcelからPythonを呼び出す~ #ExcelVBA - Qiita
最終更新日 2022年01月24日 投稿日 2020年04月28日
xlwingsでExcel VBAからPythonを実行&チュートリアルの補足 #ExcelVBA - Qiita
最終更新日 2019年07月23日 投稿日 2016年06月10日
【保存版】Excel GUIのPython実行ツールを作ろう(xlwings) #VBA - Qiita
最終更新日 2021年08月09日 投稿日 2021年08月08日
xlwings: 複数行にまたがったレコードの値を取得する #Python - Qiita
投稿日 2024年04月29日
PythonでExcelを操作する #Python - Qiita
最終更新日 2021年02月24日 投稿日 2021年01月28日
その他
Excelで使うスクリプト言語は何がいいか #ポエム - Qiita
投稿日 2024年11月27日
【Python】Python経由でPowerPointにパスワードをかける方法(win32com) #自動化 - Qiita
投稿日 2024年12月25日
PythonからExcelをwin32comで操作する #Python3 - Qiita
最終更新日 2019年10月14日 投稿日 2019年10月14日
しょーもない事務作業を快適にするためのツールを作りたいとき 〜セキュア意識の高い会社編〜 #Python - Qiita
投稿日 2024年06月28日
事例
- セルA1 起動するPythonのスクリプトの場所
- セルA2 変換元jpegファイルの場所
- セルA3 二値化する閾値
- セルA4 二値化変換後のjpegファイルの場所
(使い方)
- 任意のB列で右クリックする
- 右クリックしたcellの右側のセル(C列)に二値化変換後の画像が挿入される
「Run メソッド」が見つからなかったので、以下はその事例。
Attribute VB_Name = "Excel2Python"
Option Explicit
'Excel2Python:EXCELから外部toolを呼び出し結果を取り込む例
' ① EXCELのA列に起動するPythonのスクリプトと引数を書く(固定)
' ② 任意のB列で右クリックする(Target As Range)
' ③ 右クリックしたcellの右側のセル(C列)に画像を挿入する
Sub test(Target As Range)
Dim ws As Worksheet
Set ws = Target.Parent 'TargetのWorksheet
' Application
' └ Wokbook
' └ Worksheet ←Target.Parent
' └ Range ←Target
Dim pSFPath As String
pSFPath = ws.Range("a1").Value 'python scriptの場所
Dim sourceJFPath As String
sourceJFPath = ws.Range("a2").Value '変換元jpegファイルの場所
Dim tValue As String
tValue = ws.Range("a3").Value '閾値
Dim outputJFPath As String
outputJFPath = ws.Range("a4").Value '2値画像のファイルパス
' python script起動
Dim sObj As Object
Set sObj = CreateObject("WScript.Shell")
sObj.Run "python " & pSFPath & " " & sourceJFPath & " " & tValue & " " & outputJFPath, 0, True
' 0 : コマンドプロンプトの非表示、 True : 同期(python script終了までVBAの処理を待つ)
' Shell "python " & pSFPath & " " & sourceJFPath & " " & tValue & " " & outputJFPath, vbNormalFocus
' '->Shellは非同期のため、ファイル作成前に画像表示に行ってしまう
' /* pythonで画像処理 */
' 画像貼り付け
Dim pic As Shape
Set pic = ws.Shapes.AddPicture(outputJFPath, False, True, Left:=Target.Next.Left, Top:=Target.Top, Width:=-1, Height:=-1)
' Shapes.AddPicture メソッド (Microsoft.Office.Interop.Excel) | Microsoft Learn
' https://learn.microsoft.com/ja-jp/dotnet/api/microsoft.office.interop.excel.shapes.addpicture
End Sub
右クリックしたときに起動させるため、該当シートに記載。
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "Sheet"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Option Explicit
' 右クリック押下
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
' B列で起動
If Target.Column = 2 Then
Call test(Target)
End If
End Sub
二値化するためのPythonスクリプト。
#ライブラリのインポート
import cv2
import sys
# 引数1が開く画像ファイル名
file_name = sys.argv[1]
# 引数2が閾値
img_thres = int(sys.argv[2])
# 引数3が保存先
file_path = sys.argv[3]
# 画像を開く
#pic=cv2.imread(file_name)
#cv2.imshow('Picture', pic)
# 画像をグレースケール化
pic_gray=cv2.imread(file_name,0)
# 閾値で二値化
ret, img_binary = cv2.threshold(pic_gray, img_thres, 255, cv2.THRESH_BINARY)
# 画像を保存
cv2.imwrite(file_path, img_binary)
# 画像を開く
cv2.imshow('Binary', img_binary)
cv2.waitKey(0)
cv2.destroyAllWindows()
補足
自分の環境では問題なかったが、環境により以下のエラーが出る場合もあるようです。
NGが出る場合、もしかして、下側のようになっているのかしら……。