VSCodeの拡張機能の備忘録

VSCodeの拡張機能の備忘録

VSCodeを使おうかと思って拡張機能をいろいろとチェックしていたけど、多すぎてよくわからなくなりそうなので備忘録。


Material Theme

アイコンがわかりやすくなる

Material Icon Theme

拡張子に合わせてアイコンを表示してくれる拡張機能です。

Japanese Language Pack for Visual Studio Code

VSCodeを日本語化してくれる

Bracket Pair Colorizer 2

対応するかっこの色を変えて強調してくれる

indent-rainbow

インデントを虹色に表示してくれる拡張機能です。

Rainbow CSV

csvやtsv形式のファイルで列ごとに色分けして表示してくれる拡張機能です。

Git Graph

コミット履歴をツリー形式で表示してくれる拡張機能です。

GitLens

コミット履歴をツリー形式で表示してくれる拡張機能です。

Tabnine

コード補完機能

Git History

サイドバーにGitLensのアイコンが表示されます。
リポジトリ一覧からブランチのコミット履歴を確認できたり、ファイル履歴、行履歴、コミットの検索等が行えます。

Draw.io Integration

Draw.ioのVSCode拡張機能です。

SQLite

SQLiteを実行できる

SQL Formatter

SQLを整形できる

Markdown Preview Enhanced

プレビューの表示を見やすくする

MarkDownのプレビューは下記のCSSにカスタマイズ

(コマンドパレット:>markdown preview enhanced:customize css)


.markdown-preview.markdown-preview {
  // modify your style here
  // eg: background-color: blue;
  h1,
  h2,
  h3,
  h4,
  h5,
  h6 {
    font-family: "Gothic-UI";
    font-size: 1.2em;
  }

  body {
    font-family: "Gothic-UI";
  }
  [class*="language"] {
    font-family: "MyricaM M";
  }
  .task-list-item-checkbox {
    font-family: "Gothic-UI";
    font-size: smaller;
  }
  /**以下の部分**/
  h1 {
    counter-reset: chapter;
    font-size: 1.8em;
    border-style:solid;
    border-width: 0 0 3px 0;
  }

  h2 {
    counter-reset: sub-chapter;
    font-size: 1.5em;

    border-style: solid;
    border-color: silver;
    border-width: 0 0 1px 0;
  }

  h3 {
    counter-reset: section;
    border-style: solid;
    border-color: rgb(99, 99, 99);
    border-width: 0 0 0.5px 0;
  }

  h2::before {
    counter-increment: chapter;
    // content: counter(chapter) ". ";
  }
  h3::before {
    counter-increment: sub-chapter;
    // content: counter(chapter) "." counter(sub-chapter) ". ";
  }
  h4::before {
    counter-increment: section;
    // content: "(" counter(section) ") ";
  }
}


Markdown All in One

マークダウンに必要な機能がいろいろと入っている

Project Manager

複数のプロジェクトを同時に開くことができるようになる

Tabnine

コード補完機能

気になる機能

Pandoc

Markdownを利用してWordファイルを作成できるようになりたいけど、pandocをインストールする必要があるみたいなので悩ましい。

VBAで画像を表示し、スクロールバーを表示させる


◆概要
 VBAのフォームに画像を表示する際に、スクロールバーを付けて表示させる。
同じ様式の画像の差異をチェックするために、Excelの選択行にファイルパスを設定して起き、カーソル移動で画像の表示を変更する。
スクロールバーを表示させるためにFrameコントロールを利用するが、ScrollHeightとScrollWidthに設定する値が難しい。いろいろとネットを見ているとLoadPictureで読み込んだ画像に「24/635」をかけることで、画像プロパティの詳細設定にある幅、大きさを算出することができる。0.0378をかけているサンプルも多い
※24はビット深さ?635はわからない・・・。
    Dim obj As Object
    Set obj = LoadPicture(fstrPath)
    '画像の大きさはピクセルなので単位変換
    'MsgBox "H" & CLng(obj.Height * 24 / 635) & " W" & CLng(obj.Width * 24 / 635)
    Frame1.ScrollHeight =  CLng(obj.Height * 24 / 635)
    Frame1.ScrollWidth = CLng(obj.Width * 24 / 635)
なんだか係数の理由がわからないのが怖いので、今回はImageコントロールを使って幅と大きさを取得する。

◆ユーザーフォームのマクロ

画面上にImageコントロールとFrameコントロールを配置する。
fstrPathには画像パスを設定する。
------------------------------------------------------------------

Public fstrPath As String
Public Sub SetImage()
    Dim obj As Object
    Set obj = LoadPicture(fstrPath)
    
    'AutoSizeをTrueにしておいて画像に合わせてImageコントロールのサイズが変わるようにしておく
    Image1.Visible = False
    Image1.AutoSize = True
    Image1.Picture = obj
    
    Frame1.ScrollBars = fmScrollBarsBoth
    Frame1.ScrollHeight = Image1.Height
    Frame1.ScrollWidth = Image1.Width
    Frame1.Picture = obj

    '◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆
    '必要であればスクロールの初期値位置を設定する
    Frame1.ScrollTop = 500
    Frame1.ScrollLeft = 200
    Frame1.Zoom = 80
    '◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆
    
End Sub

◆シート側のマクロ

ユーザーフォームを先に宣言しておいて、表示したままExcelの選択行が変わったタイミングで画像だけ入れ替える。画像を見ながらひたすらEnterキーを押すことで画像だけ切り替えることができる。
------------------------------------------------------------------
  
Private frm As UserForm1
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
  '例として画像のパスをA列の1行目から6行目までに設定
    If 1 <= Target.Row And Target.Row <= 6 Then
        If frm Is Nothing Then
            Set frm = New UserForm1
            frm.Show vbModeless
        End If
        
        frm.fstrPath = Sheet1.Range("A" & Target.Row)
        frm.SetImage
        Sheet1.Select
        
    End If
End Sub


VBAのListViewで利用する共通関数(VBAでのListViewの設定方法)

 VBAのListViewが復活したいまさらながらに知ったので、共通関数として必要そうなものをつくってみた。共通モジュールに「modListView」を作って中に放り込んでおけばいろいろと使える・・・はず。

******* 画面での使い方 *******
Private Const COL_1_No As String = "_No"
Private Const COL_2_NAME As String = "_Name"
Private Const COL_3_COUNT As String = "_COUNT"
Private Sub CommandButton2_Click()
    Call SetData
End Sub
Private Sub LvSample_DblClick()
    MsgBox GetLvValueIdx(lvSample, lvSample.SelectedItem.Index, COL_1_No)
End Sub
Private Sub UserForm_Initialize()
    
    Call ControlInit
    
End Sub

Private Sub ControlInit()
    
    Call LvSample_Initialize
End Sub

'ListViewにテストデータを設定する
Private Sub SetData()
    lvSample.ListItems.Clear
    Dim i As Integer
    'データ設定方法1
    For i = 0 To 10
        lvSample.ListItems.Add
            
        Call SetLvValueIdx(lvSample, i + 1, COL_1_No, i)
        Call SetLvValueIdx(lvSample, i + 1, COL_2_NAME, "日本 太郎" & i)
        Call SetLvValueIdx(lvSample, i + 1, COL_3_COUNT, "1")
    Next
    
    'データ設定方法2
    Dim item As ListItem
    For i = 0 To 10
        
        Set item = lvSample.ListItems.Add
        
        Call SetLvValue(lvSample, item, COL_1_ATENA, "2 - " & i)
        Call SetLvValue(lvSample, item, COL_2_NAME, "日本 太郎2 - " & i)
        Call SetLvValue(lvSample, item, COL_3_COUNT, "1")
        '色変更サンプル
        If i = 1 Or i = 5 Then
            item.ForeColor = RGB(255, 0, 0)
        End If
        
        Set item = Nothing
        
    Next
End Sub

Private Sub LvSample_Initialize()
    
    'ListViewの共通プロパティ設定
    Call SetListViewProperty(lvSample)
    
    'ListViewの列を設定する
    With lvSample
        .ColumnHeaders.Add , COL_1_NO, "番号"
        .ColumnHeaders.Add , COL_2_NAME, "名前"
        .ColumnHeaders.Add , COL_3_COUNT, "数"
    End With
End Sub


*****************************

******* modListView の中身********
Public Sub SetListViewProperty(ByRef lv As ListView)
    With lv
        .View = lvwReport           ''表示
        .LabelEdit = lvwManual      ''ラベルの編集
        .HideSelection = False      ''選択の自動解除
        .AllowColumnReorder = True  ''列幅の変更を許可
        .FullRowSelect = False       ''行全体を選択
        .Gridlines = True           ''グリッド線
    End With
End Sub
'----------------------------------------------------------------------------------------------------------
'関数:列名からリストビューの値を取得する
'----------------------------------------------------------------------------------------------------------
Public Function GetLvValue(ByRef lv As ListView, ByRef lvItem As ListItem, ByVal strColKey As String) As String
    GetLvValue = ""
    
    Dim intColIdx As Integer
    intColIdx = GetColIdx(lv, strColKey)
    
    If intColIdx = -1 Then
        MsgBox "[エラー]関数の指定が間違っています。関数名:GetLvValue"
        Exit Function
    End If
    
    If intColIdx = 1 Then
        GetLvValue = lv.ListItems(lngItemIdx).Text
    Else
        GetLvValue = lv.ListItems(lngItemIdx).SubItems(intColIdx - 1)
    End If
    
End Function
'----------------------------------------------------------------------------------------------------------
'関数:列名からリストビューの値を取得する
'----------------------------------------------------------------------------------------------------------
Public Function GetLvValueIdx(ByRef lv As ListView, ByVal lngItemIdx As Long, ByVal strColKey As String) As String
    GetLvValueIdx = ""
    
    Dim intColIdx As Integer
    intColIdx = GetColIdx(lv, strColKey)
    
    If intColIdx = -1 Then
        MsgBox "[エラー]関数の指定が間違っています。関数名:GetLvValue"
        Exit Function
    End If
    
    If intColIdx = 1 Then
        GetLvValueIdx = lv.ListItems(lngItemIdx).Text
    Else
        GetLvValueIdx = lv.ListItems(lngItemIdx).SubItems(intColIdx - 1)
    End If
    
End Function

'----------------------------------------------------------------------------------------------------------
'関数:ListViewの指定項目の値を行Indexを指定して設定する
'----------------------------------------------------------------------------------------------------------
Public Sub SetLvValueIdx(ByRef lv As ListView, ByVal lngItemIdx As Long, ByVal strColKey As String, ByVal strValue As String)
    Dim intColIdx As Integer
    intColIdx = GetColIdx(lv, strColKey)
    
    If intColIdx = -1 Then
        MsgBox "[エラー]関数の指定が間違っています。関数名:SetLvValueIdx"
        Exit Sub
    End If
    
    If intColIdx = 1 Then
        lv.ListItems(lngItemIdx).Text = strValue
    Else
        lv.ListItems(lngItemIdx).SubItems(intColIdx - 1) = strValue
    End If
    
End Sub
'----------------------------------------------------------------------------------------------------------
'関数:ListViewの指定項目の値をListItemを指定して設定する
' 例: Dim item As ListItem
'       Set item = lvSample.ListItems.Add
'    Call SetLvValue(lvSample,item,"COL1_NAME","テスト 太郎")
'----------------------------------------------------------------------------------------------------------
Public Sub SetLvValue(ByRef lv As ListView, ByRef lvItem As ListItem, ByVal strColKey As String, ByVal strValue As String)
    Dim intColIdx As Integer
    intColIdx = GetColIdx(lv, strColKey)
    
    If intColIdx = -1 Then
        MsgBox "[エラー]関数の指定が間違っています。関数名:SetLvValue"
        Exit Sub
    End If
    
    If intColIdx = 1 Then
        lvItem.Text = strValue
    Else
        lvItem.SubItems(intColIdx - 1) = strValue
    End If
    
End Sub
'----------------------------------------------------------------------------------------------------------
'関数:列名からListViewの列Indexを取得する
'----------------------------------------------------------------------------------------------------------
Private Function GetColIdx(ByRef lv As ListView, ByVal strColKey As String) As Integer
    Dim i As Integer
    GetColIdx = -1
    For i = 1 To lv.ColumnHeaders.Count
        If lv.ColumnHeaders(i).Key = strColKey Then
            GetColIdx = i
            Exit Function
        End If
    Next
End Function
*****************************


フォルダ監視バッチ

特定のフォルダを監視しておいて、特定のファイルが作成されたら別の処理を実行するバッチを作成してみた。
用途としては、OCR処理をするにあたって、特定の共通フォルダを監視しておいて、特定のファイルが作成されたらOCRジョブを実行する。
もちろんOCR以外にも特定のファイルがおかれたら別処理を実行するような仕組みもできる。

HTAアプリケーションで作ろうかとも思ったけどサポートがいつまで続くかわからないし、たいして画面に表示することもないので、いろいろ考えた結果、バッチで十分じゃないのかなぁと。


<処理例>
 ・「CheckFolder.txt」に監視したいフォルダ名を複数行入力しておく
 ・監視バッチが5秒おきに実行し、「CheckFolder.txt」を読み込んで1行ずつ読み込む
   ・指定されたフォルダに「Job.txt」が作成されているかチェックする
   ・Job.txtが作成されていたら、ソフトを起動するコマンドを実行する
    処理後にフォルダ名を変更するなどの処理が必要なら必要に応じてVBSを実行する
    VBSにも引数を渡すことができる
 ・最初の処理に戻る

◆フォルダを監視するバッチ
-------- CheckFolder.txtの内容 ------

C:\Users\SampleUser\Desktop\Yosiki1
C:\Users\SampleUser\Desktop\Yosiki2

----------------------------------------

-------- バッチの内容 ------
@echo off
:loop

rem ReadFolderを開く
echo 処理を終了する場合はCtrl+Cを押下してください。
echo --- 処理実行 ---

for /f %%v in (CheckFolder.txt) do (
echo [%%v]をチェックします...
if exist %%v\Job.txt (
echo VBSを実行する
) else (
echo Job.txtが存在しません
)
)

rem 5秒待ちます
timeout 5

rem コマンドプロンプトの内容をクリア
cls

goto loop
------------------------------

VBAでStringを高速に扱う

Insert分を19万件分実行している処理が非常に遅い。
SQLを100件ずつまとめて実行しているけどやはり遅い。
文字列結合で遅くなっているので.NETであるStringBuilderと同じようなものがないか調べたところ、作っているサイトがあったのでメモ。
https://excel-ubara.com/excelvba4/EXCEL271.html

ー---
Option Explicit

Private sBuf As String
Private iBuf As Long

Private Sub Class_Initialize()
    sBuf = String$(32768, vbNullChar)
    iBuf = 0
End Sub

Public Sub Append(ByRef sValue As String)
    If iBuf + Len(sValue) > Len(sBuf) Then
        sBuf = sBuf & String$(CLng(Len(sBuf) * 2) + Len(sValue), vbNullChar)
    End If
    Mid(sBuf, iBuf + 1) = sValue
    iBuf = iBuf + Len(sValue)
End Sub

Public Function ToString() As String
    ToString = Left$(sBuf, iBuf)
End Function

VBA Recordsetの利用について

 VBAでDataTableに似たものを利用したいと思っていろいろと調べているとRecordsetがいい感じとのことだったので調べて必要そうなところを抜粋してメモしている。

Private Sub Sample()
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    
'▽Recordse定義
     Dim myRS As ADODB.Recordset
     Set myRS = New ADODB.Recordset
     With myRS.Fields
          .Append "商品番号", adVarWChar, -1
          .Append "番号", adVarWChar, -1
     End With
     myRS.Open

'▽データ取り込み-----------------------------------------
    Dim i As Long
    Dim FieldList As Variant: FieldList = Array("商品番号", "番号")
    i = 2
    Do
        myRS.AddNew FieldList, CreateArrayData(Sheet2.Range("A" & i & ":B" & i).Resize(1, 2).Value)
        i = i + 1
    Loop Until IsEmpty(Sheet2.Cells(i, 1))
     
     myRS.MoveFirst
    
'Recordsetデータ検索-----------------------------------------
    i = 2
    Do
        myRS.Filter = "商品番号 = '" & Sheet1.Cells(i, 1).Value & "'"
        Sheet1.Cells(i, 2) = myRS!番号
        i = i + 1
        If i Mod 1000 = 0 Then
        End If
    Loop Until IsEmpty(Sheet1.Cells(i, 1))
'閉じる
     myRS.Close
     Set myRS = Nothing

    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    
End Sub

Function CreateArrayData(SecDimArray As Variant) As Variant
     Dim myVar As Variant
     Dim i As Long
     ReDim myVar(0 To UBound(SecDimArray, 2) - 1)
     For i = 0 To UBound(myVar)
          myVar(i) = SecDimArray(1, i + 1)
     Next
     CreateArrayData= myVar
End Function

備忘録 Having句で集計関数を利用する

 HAVING句をうまく利用する
 
 意外と思いつかなかったけど、HAVING句でCASE句を利用することができる
 ※例は適当です。グループの中で条件を満たしていないものがあるかどうかのチェックができます。
 
  ・会社ごとに振込先口座を持っている
  ・グループ会社の中で異なる振込先があるグループがあるか
 
   (例)
    
   
    会社CD |   会社名   | グループ会社CD | 請求会社CD | 親会社CD | 銀行CD | 支店CD | 口座番号 | 口座名義人
    00001  |テスト1    | 001            | 00001      |  00001   |  0001  |  002   | 1234567  | カ)テスト1
    00002  |テスト1-1   | 001            | 00002      |  00001   |  0001  |  002   | 0004567  | カ)テスト2
    00003  |テスト1-2   | 001            | 00001      |  00001   |  0001  |  002   | 1234567  | カ)テスト1
    10001  |テスト2    | 002            | 10001      |  10001   |  0001  |  002   | 1234567  | カ)テスト2
    10002  |テスト2-1   | 002            | 10001      |  10001   |  0001  |  002   | 1234567  | カ)テスト2
    
    
    -- 「請求先」が「親会社」になっていないデータが混じっているグループ会社を抽出
  -- グループCDで集約を行い、グループCDでまとめた件数=レコードの中で「請求会社CD」
  SELECT グループ会社CD
  FROM 契約会社テーブル
  GROUP BY グループ会社CD
  HAVING COUNT(*) <> SUM(CASE 
                        WHEN 請求会社CD = 親会社CD THEN 1 
                        ELSE 0 
                    END) AS 抽出対象
  上記のデータ例で行くと「グループ会社CD:001」が抽出される
  
 集計関数の中にもCASE式が書けるって初めて知ったときに結構衝撃だったけど、月ごとの集計結果を列で持ちたいときとかにも使えるので素晴らしい。
 
  SELECT 
         商品品種名
        ,SUM(CASE WHEN SUBSTR(売上日,5,2) = '01' THEN 売上金額 ELSE 0 END) AS 1月売上
        ,SUM(CASE WHEN SUBSTR(売上日,5,2) = '02' THEN 売上金額 ELSE 0 END) AS 2月売上
        ,SUM(CASE WHEN SUBSTR(売上日,5,2) = '03' THEN 売上金額 ELSE 0 END) AS 3月売上
        ,SUM(CASE WHEN SUBSTR(売上日,5,2) = '04' THEN 売上金額 ELSE 0 END) AS 4月売上
             ・
             ・
             ・
  FROM 売上テーブル
  WHERE 売上日 BETWEEN '20210101' AND '20211231'
  GROUP BY 商品品種名
             
  
  
 

PowerShellでWPFアプリケーションをBindingするときの注意点

 1.PowerShellでWPFアプリケーションのBindingについて マニアックだけどPowerShellでWPFアプリケーションを作っている。INotifyChangedを実装したいけど、PowerShellにはgetterやsetterがないので通知が発行できない。 そ...