一つ目
Option Explicit
'Windows APIの宣言(ユーザーフォームを最前面に表示する処理で使用)
#If VBA7 Then
' 64ビット版のOffice用の宣言
'ユーザーフォームを最前面に表示する処理で使用
Private Declare PtrSafe Function SetWindowPos Lib "user32" (ByVal hWnd As LongPtr, ByVal hWndInsertAfter As LongPtr, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal uFlags As Long) As Long
Private Declare PtrSafe Function FindWindowA Lib "user32" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
#Else
' 32ビット版のOffice用の宣言
'ユーザーフォームを最前面に表示する処理で使用
Private Declare Function SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal uFlags As Long) As Long
Private Declare Function FindWindowA Lib "user32" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
#End If
Private Const SWP_NOMOVE As Long = &H2
Private Const SWP_NOSIZE As Long = &H1
Private Const HWND_TOPMOST As Long = -1
Private Const HWND_NOTOPMOST As Long = -2
Private Const SWP_NOACTIVATE As Long = &H10
'ユーザーフォームを最前面に表示する処理
Private Sub SetTopMost()
Dim hWnd As LongPtr
hWnd = FindWindowA(vbNullString, Me.Caption)
If hWnd <> 0 Then
SetWindowPos hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE
End If
End Sub
'ユーザーフォームがアクティブになった際の処理
Private Sub UserForm_Activate()
SetTopMost
End Sub
'########################
'# #
'# 仮データ取り込み #
'# #
'########################
'「仮データ取り込み」ボタンをクリックした場合の処理
Private Sub CommandButton2_Click()
Call InitializeSheet
ImportUTF8CSV
End Sub
'CSVファイルを取り込む
Sub ImportUTF8CSV()
Dim conn As Object
Dim rs As Object
Dim filePath As String
Dim sheetName As String
Dim query As String
'ファイル選択ダイアログを表示してCSVファイルを選択
filePath = Application.GetOpenFilename("CSVファイル (*.csv), *.csv", , "CSVファイルを選択してください")
' ファイル選択がキャンセルされた場合は処理を終了
If filePath = "False" Then Exit Sub
' データを貼り付けるシート名を指定
sheetName = "Sheet1"
' ADODB.Connectionオブジェクトを作成
Set conn = CreateObject("ADODB.Connection")
' ADODB.Recordsetオブジェクトを作成
Set rs = CreateObject("ADODB.Recordset")
' CSVファイルへの接続文字列を設定
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & _
Left(filePath, InStrRev(filePath, "\")) & ";" & _
"Extended Properties=""text;HDR=Yes;FMT=Delimited;CharacterSet=65001;"""
' 接続を開く
conn.Open
' クエリを設定
query = "SELECT * FROM [" & Mid(filePath, InStrRev(filePath, "\") + 1) & "]"
' クエリを実行してデータを取得
rs.Open query, conn, 1, 3
' データをシートに貼り付け
ThisWorkbook.Sheets("Sheet1").Cells(1, 1).CopyFromRecordset rs
' 接続とレコードセットを閉じる
rs.Close
conn.Close
' オブジェクトを解放
Set rs = Nothing
Set conn = Nothing
ThisWorkbook.Save ' 現在のファイル名で保存
End Sub
'####################
'# #
'# 情報入力 #
'# #
'####################
Private Sub CommandButton3_Click()
' UserForm1を非表示にする
Me.Hide
' 入力フォームを表示する
UserForm2.Show
' UserForm2が閉じられたらUserForm1を再表示する
Me.Show
End Sub
'####################
'# #
'# ファイル出力 #
'# #
'####################
Private Sub CommandButton4_Click()
ExportSheetToUTF8CSV
End Sub
' ADOライブラリを参照設定する必要があります
' 参照設定方法: VBAエディタで [ツール] -> [参照設定] -> "Microsoft ActiveX Data Objects X.X Library" にチェックを入れる
Function ConvertSheetToCSVString(sheet As Worksheet) As String
Dim csvString As String
Dim row As Range
Dim cell As Range
csvString = ""
For Each row In sheet.UsedRange.Rows
Dim rowString As String
rowString = ""
For Each cell In row.Cells
rowString = rowString & """" & Replace(cell.Value, """", """""") & """," ' ダブルクオーテーションをエスケープ
Next cell
' 最後のカンマを削除して改行を追加
rowString = Left(rowString, Len(rowString) - 1) & vbCrLf
csvString = csvString & rowString
Next row
ConvertSheetToCSVString = csvString
End Function
Sub ExportSheetToUTF8CSV()
Dim sheet As Worksheet
Dim csvString As String
Dim filePath As Variant
Dim stream As Object
' 出力するシートを指定
Set sheet = ThisWorkbook.Sheets("Sheet1") ' "Sheet1" を適切なシート名に変更
' CSV文字列に変換
csvString = ConvertSheetToCSVString(sheet)
' ファイル保存ダイアログを表示
filePath = Application.GetSaveAsFilename(FileFilter:="CSV Files (*.csv), *.csv", Title:="保存先を指定してください")
' ユーザーがキャンセルを押した場合の処理
If filePath = False Then
MsgBox "保存がキャンセルされました。"
Exit Sub
End If
' ADOストリームオブジェクトを作成
Set stream = CreateObject("ADODB.Stream")
stream.Type = 2 ' テキストストリーム
stream.Charset = "utf-8"
stream.Open
' UTF-8 BOMを書き込む
stream.WriteText ChrW(&HFEFF)
' CSV文字列を書き込む
stream.WriteText csvString
' ファイルに保存
stream.SaveToFile filePath, 2 ' 2 = adSaveCreateOverWrite
stream.Close
MsgBox "CSVファイルのエクスポートが完了しました。"
End Sub
'##########################
'# #
'# 閉じるボタンの処理 #
'# #
'##########################
'閉じるボタンをクリックした場合の処理
Private Sub CommandButton1_Click()
' ウィンドウを元に戻してエクセルシートを表示する
ThisWorkbook.Windows(1).Visible = True
Application.WindowState = xlMaximized
' ユーザーフォームを閉じる
Unload Me
End Sub
二つ目
Option Explicit
Private Sub UserForm_Initialize()
' フォーム内のすべてのコントロールのフォントサイズを指定
Call SetAllControlsFontSize(Me, 14)
'年月日を初期化する
Date_Initialize
'都道府県コンボボックスを初期化する
Prefectures_Initialize
End Sub
Private Sub Date_Initialize()
' ===== 和暦コンボボックスの設定 =====
'元号を取得
Dim eras As Collection
Dim era As Variant
Set eras = GetEraCollection()
'和暦を設定
For Each era In eras
cboLostDateFromEra.AddItem era(0) ' 表示文字を追加
cboLostDateToEra.AddItem era(0)
cboLostDateFromEra.List(cboLostDateFromEra.ListCount - 1, 1) = era(1) ' コードを隠し追加
cboLostDateToEra.List(cboLostDateFromEra.ListCount - 1, 1) = era(1)
Next era
'初期値に令和(4)を設定
cboLostDateFromEra.ListIndex = 4
cboLostDateToEra.ListIndex = 4
'リストからの選択だけにする(ユーザー入力を抑止)。
cboLostDateFromEra.Style = fmStyleDropDownList
cboLostDateToEra.Style = fmStyleDropDownList
'午前、午後のコンボボックスの設定
Dim ampm As Collection
Dim timePeriod As Variant
Set ampm = GetAmPmCollection()
'和暦を設定
For Each timePeriod In ampm
cboLostDateFromAmPm.AddItem timePeriod(0) ' 表示文字を追加
cboLostDateToAmPm.AddItem timePeriod(0)
cboLostDateFromAmPm.List(cboLostDateFromAmPm.ListCount - 1, 1) = timePeriod(1) ' コードを隠し追加
cboLostDateToAmPm.List(cboLostDateToAmPm.ListCount - 1, 1) = timePeriod(1)
Next timePeriod
'初期値に令和(4)を設定
cboLostDateFromAmPm.ListIndex = 0
cboLostDateToAmPm.ListIndex = 0
'リストからの選択だけにする(ユーザー入力を抑止)。
cboLostDateFromAmPm.Style = fmStyleDropDownList
cboLostDateToAmPm.Style = fmStyleDropDownList
End Sub
'都道府県のコンボボックスの初期化を行う
Private Sub Prefectures_Initialize()
Dim ws As Worksheet
Dim rng As Range
Dim cell As Range
' シートを指定
Set ws = ThisWorkbook.Sheets("都道府県等コード")
' リストの範囲を指定
Set rng = ws.Range("A2:B48")
' コンボボックスに項目を追加
With cboPrefecture
.Clear ' 既存の項目をクリア
For Each cell In rng.Columns(2).Cells
If Not IsEmpty(cell.Value) Then
' コンボボックスに表示するアイテムを追加
.AddItem cell.Value
' アイテムに対応するデータ(コード)を記録するための設定
.List(.ListCount - 1, 1) = cell.Offset(0, -1).Value
End If
Next cell
' 列の幅を調整(オプション)
.ColumnWidths = "30; 0" ' 表示用の列幅を調整
End With
'初期値を設定
cboPrefecture.ListIndex = 33
'リストからの選択だけにする(ユーザー入力を抑止)。
cboPrefecture.Style = fmStyleDropDownList
End Sub
'市区町村コードのDictionalyを作成する
Sub SetCityDictionary()
Dim ws As Worksheet
Dim rng As Range
Dim cell As Range
Dim dictCities As Dictionary
Dim dictCityList As Dictionary
Dim prefCode As String
' シートを指定
Set ws = ThisWorkbook.Sheets("都道府県等コード")
' リストの範囲を指定
Set rng = ws.Range("G2:I" & ws.Cells(ws.Rows.Count, "G").End(xlUp).row)
' 市区町村名の辞書を作成
Set dictCities = New Dictionary
' データを辞書に格納
For Each cell In rng.Columns(1).Cells
prefCode = Left(cell.Value, 2)
Debug.Print prefCode
If Not dictCities.Exists(prefCode) Then
Set dictCityList = New Dictionary
dictCities.Add prefCode, dictCityList
Else
'Set dictCityList = dictCities(prefCode)
End If
'dictCityList.Add cell.Offset(0, 1).Value, cell.Offset(0, 2).Value
Next cell
End Sub
Private Sub cboPrefecture_Change()
Dim selectedCode As String
' 選択されたアイテムに対応するコードを取得
If cboPrefecture.ListIndex <> -1 Then
selectedCode = cboPrefecture.List(cboPrefecture.ListIndex, 1)
MsgBox "選択されたコード: " & selectedCode
End If
End Sub
三つ目
Option Explicit
'CSVファイルを取り込むシートを初期化する
Sub InitializeSheet()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1") ' シート名を適宜変更
' シートを初期化する
ws.Cells.ClearContents ' セルの値をクリア
ws.Cells.ClearFormats ' セルの書式をクリア
ws.Cells.ClearComments ' セルのコメントをクリア
ws.DrawingObjects.Delete ' オブジェクトを削除
ThisWorkbook.Save ' 現在のファイル名で保存
End Sub
'フォーム内の要素のフォントサイズを変更する
Sub SetAllControlsFontSize(ByVal parent As Object, ByVal fontSize As Single)
Dim ctrl As Control
' 親コントロール内のすべてのコントロールをループ
For Each ctrl In parent.Controls
' フォントサイズを設定可能なコントロールの場合
On Error Resume Next
ctrl.Font.Size = fontSize
On Error GoTo 0
' コントロールがContainer(フレームなど)の場合、その内部のコントロールも設定
If TypeOf ctrl Is MSForms.Frame Or TypeOf ctrl Is MSForms.MultiPage Or TypeOf ctrl Is MSForms.TabStrip Then
Call SetAllControlsFontSize(ctrl, fontSize)
End If
Next ctrl
End Sub
'元号のコレクションを返す
Function GetEraCollection()
Dim eras As Collection
Set eras = New Collection
eras.Add Array("明治", "001")
eras.Add Array("大正", "002")
eras.Add Array("昭和", "003")
eras.Add Array("平成", "004")
eras.Add Array("令和", "005")
Set GetEraCollection = eras
End Function
'元号のコレクションを返す
Function GetAmPmCollection()
Dim ampm As Collection
Set ampm = New Collection
ampm.Add Array("午前", "001")
ampm.Add Array("午後", "002")
Set GetAmPmCollection = ampm
End Function
Sub test()
Dim ws As Worksheet
Dim rng As Range
Dim cell As Range
Dim dictTmp As Dictionary '一次表
Dim dictCityList As Dictionary '都道府県コードと市区町村データの表
Dim prefCode As String
Dim previousPrefCode As String
'都道府県の切り替わりを検出する(北海道始まり)
previousPrefCode = "01"
' シートを指定
Set ws = ThisWorkbook.Sheets("都道府県等コード")
' リストの範囲を指定
Set rng = ws.Range("G2:I" & ws.Cells(ws.Rows.Count, "G").End(xlUp).row)
' 一次表を作成
Set dictTmp = New Dictionary
' 都道府県コードと市区町村データの表を作成
Set dictCityList = New Dictionary
dictCityList.CompareMode = vbTextCompare
' データを辞書に格納
For Each cell In rng.Columns(1).Cells
prefCode = Left(cell.Value, 2)
If previousPrefCode = prefCode Then
dictTmp.Add cell.Value, cell.Offset(0, 2).Value
Else
'次の県に進んだら、都道府県コードと当該都道府県のデータを書き込む
If Not dictCityList.Exists(prefCode) Then
'2桁の都道府県コードと市区町村データを書き込む
dictCityList.Add previousPrefCode, dictTmp
Set dictTmp = Nothing
Set dictTmp = New Dictionary
Else
'
MsgBox "都道府県コードに誤りがあります。処理を終了します。"
Exit Sub
End If
'処理対象の都道府県コードを変更する。
previousPrefCode = prefCode
End If
Next cell
Dim debugDict As Dictionary
Dim Key As Variant
Dim prefCD As String
prefCD = "35"
If dictCityList.Exists(prefCD) Then
Debug.Print "Exist!!"
Debug.Print dictCityList.Count
Set debugDict = dictCityList(prefCD)
For Each Key In debugDict.Items
Debug.Print Key
Next Key
debugDict.RemoveAll
Else
Debug.Print "NG"
End If
End Sub