JW_CADの外部変形e-Tableを64bitのExcel環境でも使えるようにする

# 概要

JW_CADにはエクセルの表をJW_CAD内に取り込む外部変形としてe-Tableというものがあるのですが、
2021年11月現在配布されているものは64bit版のExcelがインストールされている環境では動作せずマクロを修正する必要があるようです。
検索した限り具体的な修正方法が見当たりませんでしたが、マクロを見た感じすぐに直せそうな内容だったので公開してみることにしました。
ほかにも修正箇所はあるかもしれませんが、サンプルを取り込んでみた限りでは以下の修正だけで取り込めているように見えます。

2021年11月現在ではe-Table製作者のサイトは消滅しているそうですが、
外部変形本体は以下のサイトからダウンロードできます。
このサイトの手順の中に「外変を使用するための ruby を導入する｡」という内容がありますが、
実際にはrubyを導入する必要はありません。

http://www.yakushima-tonbo.com/jw_cad/ExceltoJww/ExceltoJww.htm#etable


# 注意事項

<font color="red">修正は自己責任です！</font>
原理上おそらく大丈夫かと思いますが、この修正によって予期せぬ不具合が発生する可能性があるかもしれません。
万が一そのようなことがあっても責任はとれませんのでご了承ください。


# 修正の前に

ExcelからVisual Basic Editorを開く必要があります。


https://office-hack.com/excel/development-tab/

https://macvba.net/vb-editor-how-to-start


よくわからない人は、Excelマクロを作っている知り合いにでもこの記事を見せて
***報酬付きで***修正をお願いしたら喜んでやってくれるんじゃないかと思います(適当)。



# 修正方法

e-Tableの中にあるetable.xlsをエクセルで開きます。
Visual Basic Editorを開き、クラスモジュールからInitCollectionを開きます。
先頭2行に以下のようなコードがありますので、

```VB
Private Declare Function GetPrivateProfileInt Lib "kernel32" Alias "GetPrivateProfileIntA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal nDefault As Long, ByVal lpFileName As String) As Long
Private Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpAppName As String, ByVal lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal inifilename As String) As Long
```

次のようにDeclareの後にPtrSafeをつけます。

```VB
Private Declare PtrSafe Function GetPrivateProfileInt Lib "kernel32" Alias "GetPrivateProfileIntA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal nDefault As Long, ByVal lpFileName As String) As Long
Private Declare PtrSafe Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpAppName As String, ByVal lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal inifilename As String) As Long
```

Excel 2010以降なら32bit版でもPtrSafeをつけた状態のまま動くらしいですが、
確認できず不安なら以下のような感じで条件付きコンパイル(#if)でコードを分岐しておいてもいいと思います。

```VB
#If Win64 Then
Private Declare PtrSafe Function GetPrivateProfileInt Lib "kernel32" Alias "GetPrivateProfileIntA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal nDefault As Long, ByVal lpFileName As String) As Long
Private Declare PtrSafe Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpAppName As String, ByVal lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal inifilename As String) As Long
#Else
Private Declare Function GetPrivateProfileInt Lib "kernel32" Alias "GetPrivateProfileIntA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal nDefault As Long, ByVal lpFileName As String) As Long
Private Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpAppName As String, ByVal lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal inifilename As String) As Long
#End If
```

https://hatena19.com/use-win-api-with-office-64bit-or-32bit-vba/

# 修正する理由

64bit版OfficeではWin32APIの宣言方法が変更になっている関係でそのままでは動かなくなっているようです。
~~MSさんなんでそんなことするの・・・~~

https://docs.microsoft.com/ja-jp/office/client-developer/shared/compatibility-between-the-32-bit-and-64-bit-versions-of-office



# 使いやすくする

個人的には不満点がいくつかあったので修正できるものは修正してみる。
全てetable.xlsにあるマクロを修正しています。

### ファイル名を描画しないようにする

e-Tableで表を貼り付けると一緒に左下にファイル名とシート名が文字列として描画されます。正直邪魔です。
「エクセルファイルのパス名を書き込む」というそれっぽい設定がありますが、チェックを外しても反映されないようです。

描画しないようにするには、etable.iniをテキストエディタで開き、FilenameFontを0にすると描画しなくなるようです。

```
DrawFilename=0
UseSolidLine=0
FilenameFont=0　←この行の値を0にする
Align=0
```

マクロで描画しないようにするには、標準モジュールのPlotFileの255行目辺りに以下のようなコードがあるので、
以下のようにPrint #ステートメントの部分をコメントアウトします。

```VB
    name_font = config.GetStr("eTable", "FilenameFont")
    name_size = CDbl(name_font)
    If name_size > 0# Then
        y2 = y2 - name_size * doc_scale
        'Print #out, "cn0 " & name_font & " " & name_font & " 0.0 9"
        'Print #out, "ch " & Format(x1) & delim & Format(y2) & " 1 0 """ & bookPath
    End If
```

もしオプションで指定したい場合は「エクセルファイルのパス名を書き込む」はetable.iniのDrawFilenameに対応しているようなので、
以下のようにFinenameFontの部分をDrawFilenameに修正すれば「エクセルファイルのパス名を書き込む」のチェックの有無で描画するしないを指定できるようになります。

```VB
    name_font = config.GetStr("eTable", "DrawFilename")
    name_size = CDbl(name_font)
    If name_size > 0# Then
        y2 = y2 - name_size * doc_scale
        Print #out, "cn0 " & name_font & " " & name_font & " 0.0 9"
        Print #out, "ch " & Format(x1) & delim & Format(y2) & " 1 0 """ & bookPath
    End If
```



### 文字をカラーで作図しない時の文字の色を黒にする

「文字をカラーで作図」設定をOFFにした時の文字色は(おそらく)フォントサイズに近い(同じ?)文字種を設定するようですが、
(文字をカラーで作図をONにした場合は文字列の先頭に制御文字を追加することで色を設定する模様)
文字の大きさによって色が変わるのはどうかと思うのと、
近い(同じ?)ものが見つからなかった場合のデフォルト色が水色(1番)なのが気に入らないので、
取得した文字種を反映せずにフォントサイズをそのまま反映させた上で色を黒(2番)に固定したい。
この部分はマクロでハードコーディングされているのでマクロ本体を修正するしかない模様。

クラスモジュールのJwFontの112行目辺りにDrawサブルーチンがあるので、以下のように修正します。


```VB
Public Sub Draw(out As Long)
    '近似文字種取得済み判定の条件分岐と真の場合のコードをコメントアウト
    'If Id > 0 Then
    '    Print #out, "cn" & Format(Id)
    'Else
        Print #out, "cn0 " & Format(FreeSize) & " " & Format(FreeSize) & " 0 2" '←この行の最後の" 0 1"を"0 2"に修正
    'End If
End Sub
```


### 表全体の枠として補助線を描画しないようにする

表を貼り付けると罫線とは別に表全体を囲むような補助線が描画されるようです。
罫線なしの表を貼り付けるとわかります。
レイヤ分けしてくれるわけでもないようなので個人的には不要かな。
補助線を描画しないようにするにもマクロを修正するしかない模様。

標準モジュールのPlotFileの240行辺りに以下のようなコードがあるので、Print #ステートメントの部分をコメントアウトします。


```VB
    'Print #out, "lc9"
    'Print #out, "lt9"
    x1 = leftPos
    y1 = topPos
    x2 = x1 + area_width
    y2 = y1 - area_height
    'Print #out, Format(x1) & delim & Format(y1) & delim & _
    '                        Format(x2) & delim & Format(y1)
    'Print #out, Format(x1) & delim & Format(y2) & delim & _
    '                        Format(x2) & delim & Format(y2)
    'Print #out, Format(x1) & delim & Format(y1) & delim & _
    '                        Format(x1) & " " & Format(y2)
    'Print #out, Format(x2) & delim & Format(y1) & delim & _
    '                        Format(x2) & delim & Format(y2)
    
```