忍者ブログ

読み取り専用で開かせてマクロの保存だけを許可するブック

2024年05月15日

会社でNAS上のファイルをみんなで編集することって結構ある。

誰かが開いていると編集権が手に入らず待ちぼうけなんてことも。


ファイル共有機能で対策はできるものの、どっちも好きじゃない。
①エクセルのブック共有機能を使う
→編集箇所が競合したときに困る

②OneDriveでファイル共有機能を使う
→保存場所がNASじゃなくなるので、使いづらい


今回は、NAS上のファイルに書き込みパスワードを設定することで、
読み取り専用で開くことを強要して、ブックに埋め込んだマクロを使って保存する方法を考えた。
PR
つづきはこちら "読み取り専用で開かせてマクロの保存だけを許可するブック"

ショートカットファイルのリンク先を置換するマクロの改良~実用版~

2024年05月07日

会社で使っているNASのリンク切れが激しい。。。
もういい加減、旧NASへのリンクは撲滅したい!

そんな思いから、NAS上にあるリンク切れショートカットファイルのリンク先をVBAを使って
一括で置換することにした。

まてよ。そういや昔に同じようなものを作ったような。。。
どこまでできてたっけか。
つづきはこちら "ショートカットファイルのリンク先を置換するマクロの改良~実用版~"

矩形選択の使い方を理解することでVBAの列記述の考え方が変わった話

2024年04月27日
VBAを使ったプログラミングだと、出力にシートを使うことがほとんど。

列ごとにタイトルを決めて、情報を集めていくけど
列の順番って結構変更したくなることが多い。

今回は、テキストエディタを活用することで、
列番号を変更する方法を紹介。
つづきはこちら "矩形選択の使い方を理解することでVBAの列記述の考え方が変わった話"

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

 | HOME | 次のページ »