忍者ブログ

空フォルダを消すクリーナバッチを再改良

2024年01月12日
昔かかった号令の影響で、NAS上に空フォルダがいっぱいの案件がある。

案件フォルダの雛形として、フォルダが用意されているものの、中身がなかったりする。

探し物をしてるとこれが実に腹立たしくて、一括で消してやりたくなった。

今回はバッチファイルでサブフォルダを含めて空のフォルダを削除するバッチについて
PR
つづきはこちら "空フォルダを消すクリーナバッチを再改良"

16進数を2進数に変換するVBAプログラムでBingと勝負してみた話

2024年01月07日
前回の2進数を10進数に変換する関数とかなり似た内容なんだけど、
16進数を2進数を変換するプログラムも作ってみた。


まず浮かぶやり方は、0~9、A~Fの文字に対する2進数を
IF文等で分岐するやり方。

なんかあんまスマートじゃないし、速度も遅そう。


もう一つは数学的に2で割った商と余りから計算するやり方。

軽く検索をかけたところ、以下のサイトがヒット。

https://vbabeginner.net/convert-hextobin/


16進数をいったん10進数に変換して、
10進数を2進数に変換するという2ステップを踏む方が高速だったとのこと。


上記のリンクの内容を信じて2ステップを踏んで処理する仕様にした。
作ったソースコードがこちら。
' %%%% 16進数から2進数へ %%%%%
Function Hex2BinEx(hex)
    If hex = "" Then
        Hex2BinEx = ""
    Else
        Dim i As Long
        For i = 1 To Len(hex)
            Hex2BinEx = Hex2BinEx & Format(Dec2BinEx(CInt("&H" & Mid(hex, i, 1))), "0000")
        Next i
    End If
End Function
Function Dec2BinEx(strDec As String)
    If strDec = "" Then Dec2BinEx = ""
    
    Dim sBin        As String   '// 2進数文字列
    Dim iRemainder  As Integer  '// 余り
    Dim dDiv        As Long   '// 商
    
    dDiv = Val(strDec)
    
    Do
        iRemainder = dDiv Mod 2
        dDiv = Int(dDiv / 2)
        sBin = CStr(iRemainder) & sBin
        If (dDiv < 2) Then
            If (dDiv = 1) Then
                sBin = CStr(dDiv) & sBin
            End If
            Exit Do
        End If
    Loop
    Dec2BinEx = sBin
End Function


リンクを張った記事の内容をFunctionモジュールにして、不要な初期化等も削除した。

出力される桁数が少なくなる不具合が出たので、
2進数は必ず4桁で出るようにformat関数で指定した。


せっかくなので、Bing AIを使って作ってみたらどうなるか試したところ、
上記のリンクで否定していたselect文で分岐する方法が出てきた。
Function Hex2BinBing(ByVal hex As String) As String
    Dim i As Long
    Dim bin As String
    For i = 1 To Len(hex)
        Select Case UCase(Mid(hex, i, 1))
            Case "0": bin = bin & "0000"
            Case "1": bin = bin & "0001"
            Case "2": bin = bin & "0010"
            Case "3": bin = bin & "0011"
            Case "4": bin = bin & "0100"
            Case "5": bin = bin & "0101"
            Case "6": bin = bin & "0110"
            Case "7": bin = bin & "0111"
            Case "8": bin = bin & "1000"
            Case "9": bin = bin & "1001"
            Case "A": bin = bin & "1010"
            Case "B": bin = bin & "1011"
            Case "C": bin = bin & "1100"
            Case "D": bin = bin & "1101"
            Case "E": bin = bin & "1110"
            Case "F": bin = bin & "1111"
        End Select
    Next i
    Hex2BinBing = bin
End Function
"高速で"というk-ワードを追加してみたけど、
出力される内容は同じで、ビット演算をしているから高速だとか言ってる。

マッピングってビット演算なの・・・?


Bingが折れないので、速度を比較してみた。
0~Fを連結した16進数16文字を1万回2進数に変換して比較してみた。
Sub discTest()
    Dim tictoc As Double
    tictoc = Timer
    Dim i As Long, x
    For i = 1 To 10000
        x = Hex2BinEx("0123456789ABCDEF")
    Next i
    Debug.Print Timer - tictoc, x
    
    tictoc = Timer
    For i = 1 To 10000
        x = Hex2BinBing("0123456789ABCDEF")
    Next i
    Debug.Print Timer - tictoc, x
    
End Sub
Hex2BinEx:自作関数  0.632秒
Hex2BinBing:Bing作成関数  0.143秒


圧倒的に負けた。。。


Bingにソースコードを貼り付けて、どちらが高速動作するか聞いたところ、

以下の2つの関数のどちらが速いかは、実際に実行して比較する必要があります。
ただし、Hex2BinBing関数は、ビット演算子を使用して高速に16進数から2進数に変換するため、
Hex2BinEx関数よりも高速である可能性があります。

とのこと。


ブログのために質問し直したら「実際に実行して比較する」の一点張り。
どうやら、Bingにソースコードを生成させた後に質問したから
自分が提案した方法を推すわけね。

VBAで2進数を10進数に変換する関数を作ってみた(LSBに対応)

2024年01月06日
会社で2進数のログを扱うことがあって、
2進数を10進数に変換する自作関数を作った。

普通と違うのは、各ビットを読む順番。
マニアックなことに左側を下位ビットとして解釈する(LSBというらしい)。

1110→7
0011→12

昔、16進数を10進数に変換しようとしてこんな関数は作ってた。

' %%%% 16進数から10進数へ %%%%%
Function Hex2DecEx(Hex)
If Hex = "" Then
    Hex2DecEx = ""
Else
    Dim i As Long
    
    For i = 1 To Len(Hex)
        Hex2DecEx = Hex2DecEx * 16 + CInt("&H" & Mid(Hex, i, 1))
    Next i
End If    
End Function

エクセルの標準関数が用意されているけど、当時アドインを入れないといけなかったのと
文字数に制限があって作った気がする。


WEBで検索したらこのサイトがクリーンヒット。よく見たらbin2decじゃん。




やった作業はめっちゃ簡単。
●HexをBinに変えて16を2に変えた
●逆順に対応できるようにフラグを用意して、逆順の場合はループを逆回し


今回作ったソースは以下の通り。
ちなみに、逆順フラグはオプションにして、省略可能にしておいた。
やった作業はめっちゃ簡単。
●HexをBinに変えて16を2に変えた
●逆順に対応できるようにフラグを用意して、逆順の場合はループを逆回し
今回作ったソースは以下の通り。
ちなみに、逆順フラグはオプションにして、省略可能にしておいた。
' %%%% 2進数から10進数へ %%%%%
Function Bin2DecEx(Bin As String, Optional lsbFlag As Long = 0)
    If Bin = "" Then
        Bin2DecEx = ""
    Else
        Dim i As Long
        If lsbFlag = 0 Then
            For i = 1 To Len(Bin)
                Bin2DecEx = Bin2DecEx * 2 + CInt("&H" & Mid(Bin, i, 1))
            Next i
        Else
            For i = Len(Bin) To 1 Step -1
                Bin2DecEx = Bin2DecEx * 2 + CInt("&H" & Mid(Bin, i, 1))
            Next i
        End If
    End If
End Function

エンジニアが作るデザインについて

2024年01月02日
今回は珍しくデザインに関するはなし。

会社で定期的に貼られるリンク。それが以下のサイト。なんの戒めなのか、やり始めた人は退職したけど、定期的にリンクを貼る文化は続いてる。

https://qiita.com/mskmiki/items/544149987475719e417b
つづきはこちら "エンジニアが作るデザインについて"

ドラッグドロップ全ファイルループモジュールその3 進捗表示機能搭載

2023年12月26日
前々回、Bing AIを使ってVBScriptのソースコードを生成して、
そのまま実行したら良好な結果を得られた。

ドラッグドロップ標準モジュール


この内容に対して、過去に作った進捗状況をファイル名で表示するモジュールを組み合わせるべく
またしてもBing AIを使って改良を試みた。
つづきはこちら "ドラッグドロップ全ファイルループモジュールその3 進捗表示機能搭載"