図面の部品表をExcelファイルに保存するSolidworksのマクロ

これは、開いている図面で実行すると部品表/BOM(Bill Of Materials)をExcelファイルで保存します。Excelのファイル名は図面のファイル名と同じです。図面ファイルと同じフォルダに保存します。Excelのマクロも使ってます。

部品表のExcelファイルを移動して発注などに使っても図面の関係がわかるようにA1セルに図面ファイルのフルパスのファイル名を入れています。

完了したら、Solidworksでは完了のメッセージを開き、Windowsエクスプローラーで保存したExcelのファイルがあるフォルダを開きます。

Sub drdBOM_xls()

    ' SolidWorksアプリケーションのインスタンスを取得
    Dim swApp As SldWorks.SldWorks
    Set swApp = Application.SldWorks

    ' アクティブなドキュメントを取得
    Dim swModel As SldWorks.ModelDoc2
    Set swModel = swApp.ActiveDoc

    If swModel Is Nothing Then
        MsgBox "アクティブなドキュメントが見つかりません。"
        Exit Sub
    End If

    ' 部品表を保持する変数
    Dim swTable As SldWorks.TableAnnotation
    Dim foundBOM As Boolean
    foundBOM = False

    ' 図面シートまたはビューを取得し、すべてのビューを巡回
    Dim swView As SldWorks.View
    Set swView = swModel.GetFirstView

    Do While Not swView Is Nothing
        ' 各ビュー内のテーブル注釈を取得
        Dim swTableAnn As SldWorks.TableAnnotation
        Set swTableAnn = swView.GetFirstTableAnnotation

        ' テーブルアノテーションを巡回
        Do While Not swTableAnn Is Nothing
            ' 部品表かどうか確認
            If swTableAnn.Type = swTableAnnotationType_e.swTableAnnotation_BillOfMaterials Then
                Set swTable = swTableAnn
                foundBOM = True
                Exit Do
            End If
            Set swTableAnn = swTableAnn.GetNext
        Loop
        
        If foundBOM Then Exit Do
        Set swView = swView.GetNextView
    Loop

    ' 部品表が見つからなかった場合
    If Not foundBOM Then
        MsgBox "部品表が見つかりませんでした。"
        Exit Sub
    End If

    ' Excelアプリケーションのインスタンスを作成
    Dim xlApp As Object
    Dim xlBook As Object
    Dim xlSheet As Object
    Set xlApp = CreateObject("Excel.Application")
    Set xlBook = xlApp.Workbooks.Add
    Set xlSheet = xlBook.Sheets(1)

    ' Excelを表示
    xlApp.Visible = True

    ' 正規表現オブジェクトを作成してHTMLタグを削除する
    Dim regex As Object
    Set regex = CreateObject("VBScript.RegExp")
    regex.Global = True
    regex.IgnoreCase = True
    regex.Pattern = "<[^>]+>" ' HTMLタグにマッチするパターン

    ' 部品表の行数と列数を取得
    Dim rowCount As Long
    Dim colCount As Long
    rowCount = swTable.rowCount
    colCount = swTable.ColumnCount

    ' 部品表データをExcelに転送
    Dim i As Long, j As Long
    Dim rawText As String
    Dim cleanText As String
    For i = 0 To rowCount - 1
        For j = 0 To colCount - 1
            rawText = swTable.DisplayedText(i, j)
            '0001先頭が0から始まる文字を数値にしないために’を入れてセルで文字列にする
            If Left(rawText, 1) = "0" Or Left(rawText, 1) = "0" Then rawText = "'" & rawText
            ' HTMLタグを削除
            cleanText = regex.Replace(rawText, "")
            xlSheet.Cells(i + 1, j + 1).Value = cleanText
        Next j
    Next i
    'A1に図面のフォルダ名+ファイル名をコメントで追加
    xlSheet.Range("A1").AddComment swModel.GetPathName
    'Excelで保存するために図面のフルパス+ファイル名の拡張子だけを削除
    Dim ss As String
    ss = Mid(swModel.GetPathName, InStrRev(swModel.GetPathName, "."))
    ss = VBA.Replace(swModel.GetPathName, ss, "")
    
    ' Excelファイルの保存
     ' 警告を無効にする
    xlApp.Application.DisplayAlerts = False
    xlBook.SaveAs ss 'Excelファイルの保存
    'xlBook.SaveAs ss & ".csv"  'CSVファイルの保存。テキストです
     ' 警告を無効にする
    xlApp.Application.DisplayAlerts = True
    xlApp.Quit  'Excel終了

    ' クリーンアップ
    Set xlSheet = Nothing
    Set xlBook = Nothing
    Set xlApp = Nothing

    MsgBox "部品表がExcelにエクスポートされました。"
    ' エクスプローラーでExcelで保存したフォルダを開く
    ss = Mid(swModel.GetPathName, InStrRev(swModel.GetPathName, "\"))
    ss = VBA.Replace(swModel.GetPathName, ss, "")
    Shell "explorer.exe " & ss, VBA.vbNormalFocus
End Sub

とりあえずの状態ですが、いずれあるフォルダ以下にある全図面ファイルの部品表を自動的にExcelファイル保存するマクロ/コードを書きたいと思います。やっぱ自動化ですよね。DX(デジタルトランスフォーメーション)っていうやつです。

chcpコードページ簡単変更プログラム

mychcp.exeを作ります。

実行するとシフトJISならUTF8、UTF8ならシフトJISに変えます。

chcpの引数の数値を毎回検索するのは面倒。

環境変数を使うっていう手もあります。

set u=65001
set j=932

とでもしておいて、chcp %j%とかchcp %u%でできます。

もうちょっとchcpのヘルプでコードの番号を表示してくれればいいのですが以下ですから。

何でほしくなったかというとPythonがutf8でないといけない。それだけです。

さて、exe化ですが。

好きなrubyでexe化しようと思いましたがなかなかです。ocranariを使ってみましたが最新版のRubyでは無理?

Pythonなら圧倒的なユーザー数ですからやってみました。以下のファイルはmychcp.pyとして保存します。

import os

os.system("chcp > .cc.txt")
f=open(".cc.txt","r")
ss=f.read()
f.close()
os.system("del .cc.txt")
s=ss.split() #array
if s[2] == "932":
    os.system('chcp 65001')
    print("utf8")
else:
    os.system('chcp 932')
    print("ShiftJIS")

#print(s[0]) #debug
#print(s[1]) #debug
#print(s[2]) #debug

Windowsのコマンドプロンプトでchcpを実行すると以下のようになる。

os.system(“chcp > .cc.txt”)で、chcp >とリダイレクトを使ってコンソールの表示をcc.txtファイルに保存する。つまり、.cc.txtには「現在のコード ページ: 932」が保存されている。このファイルをopenして、全部呼び込むf.read。ss変数には「現在のコード ページ: 932」が入っていて、split関数でスペース区切りでs変数に配列が入る。s[0]には「現在のコード」がs[1]には「ページ:」が、s[2]には「932」が入る。

if文では、シフトJIS(932)ならutf8(65004)に変更し、シフトJIS(932)で無いならelseの方をos.system(‘chcp 932’)実行する。

pyinstallerをインストールします。これがEXE化のライブラリです。Pythonはライブラリが豊富でいろいろあるが、これが有名かと。

コンソールからpip install pyinstallerとします。インストールできたら、

exe作成は、pyinstaller -F mychcp.pyです。

実行したフォルダ下にdistフォルダができてます。この中にmychcp.exeがあります。WindowsのPCならmychcp.exeファイル単体で動きます。

mychcp.exeの実行結果です。

Pythonインストール

令和5年8月30日、2023年8月30日現在

Python公式サイトの ダウンロードページ

https://www.python.org/downloads/

chromeの日本語翻訳で十分読めます。

今回は、Windowsの64ビット(私のPCはWindows10で64ビット)なので「Windows インストーラー (64 ビット)」をダウンロードしました。説明の項目には推奨と書いてました。

ダウロードフォルダにはpython-3.11.5-amd64.exe。これをダブルクリックしてインストール。

スタートメニューに以下が使えるようになってます。

インストール途中でcmd.exeコマンドプロンプト上でも使えるようにPATHの設定(Add pythone.exe to PATH)をするのでコマンドプロンプト上でpythonが使えます。

環境変数でプログラム

コマンドプロンプトだけでプログラムが書ける。Unix/Linuxの世界でシェルプログラムというが。Windowsでもシェルプログラムなんでしょうね。「Windows bash」で検索すると何とWindowsがLinuxみたいです。

ここでは、生のコマンドプロンプトでプログラムらしきことをします。条件文は使いません。

setで変数が見える。

コマンドにいきなりa=1+1は不可能。

set /aを使う

で、環境変数とは、最初からある変数です。Windowsが持っている変数。コマンドプロンプトで使える変数です。

dosこちらを参考

Rubyのirb

irbを実行すると、コマンドプロンプトみたいですが、Rubyのコマンドをすぐに実行できる。

次図は、 irbに引数-r irb/completionを付けて実行している。これで、TABキーを使うとメソッドやプロパティを補完してくれる。

次図では1.cでTABキーを入れている。

Rubyでは何と!数値の1もオブジェクトです。1のClass名はIntegerとある。1.1はFlat。”a”はString。徹底してオブジェクトです。

変数の対義語がリテラル。リテラル=文字列や数値。リテラル=定数でもいい。変数<=>定数。ですね。Rubyではリテラルすらメソッドやプロパティを持つ。わお。全部オブジェクトだわ。

irbだけでTABキーで補完できる場合は、~/.irbrcテクストファイルにrequire “irb/completion”が入ってます。~/はWindows10ではCドライブの「ユーザーズ」のログイン名。私の場合は、「C:\Users\take」です。

Pythonがなんでいいか

ライブラリが多いから。AIがどうのとか紹介する人も多いし。

それだけだ。基本、言語仕様もいろいろあってRubyの方がいいわとかあるが。

「クラスとは」から始まるJAVAのような言語は開発者向け。ライブラリを作る人向け。「クラスって複雑な変数です!」。「関数や変数を持った変数です」。こんなん作ること普段の仕事の処理では無い!。C言語なんて習っても何がうれしい?。何か装置を作るの?。って目的をしっかり決めて学ぶ。経験しないと難しいヵ?

今は、RubyとかPythonなんかのスプリクト言語で十分。

ただ、RubyもPythonもクラスについて話しはある。そこは軽く流しても何らかの処理をするコードはすぐに書ける。ExcelなどのOfficeだとVBAだがこれもクラスは利用するだけでクラスを作ることは無い!。世の中のVBAの話しいは関数までの知識、いや、引数なしでの処理の知識で蔓延している。処理手順が書ければ仕事はできる。

通常の仕事は以下のこと。処理の流れのコードが書ければ十分。

  1. 順番にする処理。マクロ。サブルーチン
  2. 引数が使える
  3. 関数が作れる。関数を値として使える
  4. 使える多くの関数を作る

最後の関数をたくさん作って日頃の業務に活用する。っていっても片手間で作るのがほとんど。作ってもなかなか整理することはできない。ホントは、次の1くらいはやりたいわ。

以下は開発者レベルだろう。

  1. 多く関数をライブラリにしている
  2. 複雑すぎてクラスを使う
  3. 複数のクラスをライブラリにして使っている

プログラムの実行スピード

スピードはいらない。
メンテナンス第一。
わかりやすさ第一。

Ruby、Pythonスクリプト言語がええ。動かしながらデバッグできんとねー。VBAも 動かしながらデバッグ できる。デバッグ中は解決に向かっている。チャンスです。はい喜んで!

プログラム用フォントMyrica

ExcelのVBAのコード用。Excel本体のように英語のフォントを選んでも日本語が使えるような二段仕立てのフォント対応ではない。コード用のフォントは日本語を含む必要がある。

Myrica (ミリカ)。ダウロードして使う。拡張子ttcをダブルクリックして「インストール」ボタンを押す。

Myrica Narrow(日本語)
ほんと狭いNarrow

特に印刷すると違いがわかる。ややこしいのが、数字のいち、小文字のエル、大文字のアイ。大文字のおー、数字のゼロ。