cls試験データシート
Option Explicit ' --------------------------------------------------------------------------------------------------------------------- ' 定数 ' --------------------------------------------------------------------------------------------------------------------- Const cnst上限レコード取得数 = 1000 ' 環境に合わせて増減 Const cnst試験データ開始行 = 5 Const cnstヘッダ行数 = 5 Const cnstテーブル物理名記載列 = 4 Const cnstテーブル名記載行idx = 1 Const cnstデータ開始行idx = 2 Const cnstデータ終了行idx = 3 Const cnstデータ終了列idx = 4 ' Private oraconn As New ADODB.Connection Private oraconn As Object ' ********************************************************************************************************************* ' 機能:コンストラクタ ' ********************************************************************************************************************* ' Public Sub Class_Initialize() Set oraconn = CreateObject("ADODB.Connection") End Sub ' ********************************************************************************************************************* ' 機能:シート上、オープン状態のテーブルのレコードをDBに取得しに行く ' ********************************************************************************************************************* ' Public Function getレコード(ByRef wb前回実行結果 As Workbook) As Workbook If ActiveSheet.Range("A1") <> "凡例" Then Call log("想定外のシートが対象となっているためProcedureを終了します。") Exit Function End If Dim obj設定シート As cls設定シート: Set obj設定シート = New cls設定シート ' データベースに接続する(必要な値は設定シートから取得) oraconn.ConnectionString = obj設定シート.getConnectionString ' On Error GoTo occurError oraconn.Open If executeCountSQL Then ' ユーザが件数を確認し続行した場合のみデータを取得 Set getレコード = executeSQL(wb前回実行結果) End If oraconn.Close Set oraconn = Nothing Exit Function occurError: Dim txtエラーメッセージ As String txtエラーメッセージ = txtエラーメッセージ & "エラー番号:" & Err.Number & vbCrLf txtエラーメッセージ = txtエラーメッセージ & Err.Description & vbCrLf txtエラーメッセージ = txtエラーメッセージ & "ヘルプファイル名:" & Err.HelpContext & vbCrLf txtエラーメッセージ = txtエラーメッセージ & "プロジェクト名:" & Err.Source MsgBox txtエラーメッセージ End End Function ' ********************************************************************************************************************* ' 機能:COUNTのSQL発行を行う。 ' カウントの結果を参照したユーザが、処理を中断した場合、FALSEを返す ' ********************************************************************************************************************* ' Private Function executeCountSQL() As Boolean ' Dim rs As ADODB.Recordset Dim rs As Object Set rs = CreateObject("ADODB.Recordset") Dim obj試験データテーブル() As cls試験データテーブル obj試験データテーブル = getテーブル座標情報 With ActiveSheet Dim i As Long For i = LBound(obj試験データテーブル) To UBound(obj試験データテーブル) ' --------------------------------------------------------------------------------------------------------- ' SQL文の作成 ' --------------------------------------------------------------------------------------------------------- ' ヘッダ部分が非表示の場合はスキップする If obj試験データテーブル(i).Hidden() Then GoTo continue End If Dim strQuery As String strQuery = obj試験データテーブル(i).createSELECT文From複数行() ' --------------------------------------------------------------------------------------------------------- ' SQL文の発行 ' --------------------------------------------------------------------------------------------------------- Dim txtCountQuery As String txtCountQuery = obj試験データテーブル(i).createCount文(strQuery) log ("発行するSQL:" & txtCountQuery) Set rs = oraconn.Execute(txtCountQuery) obj試験データテーブル(i).setDBCount結果 (rs.Fields("COUNT")) continue: Next i End With ' レコードセットをクローズする rs.Close Set rs = Nothing ' COUNTモードで実行した場合、取得予定の件数を利用者に通知する。 ' 尚、件数が上限を超えるような場合は、利用者にその旨を通知し、処理を打ち切る。 Dim txtCountList As String Dim lngレコード総数 As Long: lngレコード総数 = 0 For i = LBound(obj試験データテーブル) To UBound(obj試験データテーブル) If Not obj試験データテーブル(i).Hidden Then txtCountList = txtCountList & _ obj試験データテーブル(i).getテーブル論理名 & _ ":" _ & obj試験データテーブル(i).getDBCount結果 & " 件" & vbCrLf lngレコード総数 = lngレコード総数 + obj試験データテーブル(i).getDBCount結果 End If Next i Dim txtMsg As String If lngレコード総数 <= cnst上限レコード取得数 Then txtMsg = "総件数 " & lngレコード総数 & " 件のレコードを結果として取得します。" _ & vbCrLf & vbCrLf & txtCountList If MsgBox(txtMsg, vbOKCancel) <> vbOK Then executeCountSQL = False Exit Function End If Else txtMsg = "総件数(" & lngレコード総数 _ & " 件)が上限件数(" & cnst上限レコード取得数 & " 件)を超えています。" _ & "条件を見直して下さい。" _ & vbCrLf & vbCrLf & txtCountList MsgBox (txtMsg) executeCountSQL = False Exit Function End If executeCountSQL = True End Function ' ********************************************************************************************************************* ' 機能:COUNTのSQL発行を行う。 ' カウントの結果を参照したユーザが、処理を中断した場合、FALSEを返す ' ********************************************************************************************************************* ' Private Function executeSQL(ByRef wb前回実行結果 As Workbook) As Workbook Dim wb実行元ブック As Workbook Set wb実行元ブック = ActiveWorkbook Dim rs As Object Set rs = CreateObject("ADODB.Recordset") Dim obj試験データテーブル() As cls試験データテーブル obj試験データテーブル = getテーブル座標情報 Dim lng出力最終行 As Long lng出力最終行 = 5 ' ブックの準備 If wb前回実行結果 Is Nothing Then Dim wb実行結果 As Workbook Set wb実行結果 = Workbooks.Add wb実行元ブック.ActiveSheet.Copy Before:=wb実行結果.Sheets(1) Else Set wb実行結果 = wb前回実行結果 wb実行元ブック.ActiveSheet.Copy After:=wb実行結果.Sheets(wb実行結果.Sheets.Count) End If Dim txt実行結果シート名 As String txt実行結果シート名 = Format(Now(), "yyyymmdd_HHnnss") wb実行結果.Sheets(wb実行元ブック.ActiveSheet.Name).Name = txt実行結果シート名 If wb前回実行結果 Is Nothing Then Call 不要シート削除(wb実行結果, txt実行結果シート名) End If wb実行結果.ActiveSheet.Range("A" & lng出力最終行, ActiveCell.SpecialCells(xlLastCell)).Delete wb実行結果.ActiveSheet.Outline.ShowLevels RowLevels:=2 wb実行結果.ActiveSheet.Rows.Ungroup ' wb実行結果.AvtiveSheet.Range("F1").Value = "" ' マクロ用のガイドつぶし wb実行元ブック.Activate With ActiveSheet Dim i As Long For i = LBound(obj試験データテーブル) To UBound(obj試験データテーブル) ' --------------------------------------------------------------------------------------------------------- ' SQL文の作成 ' --------------------------------------------------------------------------------------------------------- ' ヘッダ部分が非表示の場合はスキップする If obj試験データテーブル(i).Hidden() Then GoTo continue End If Dim txtQuery As String txtQuery = obj試験データテーブル(i).createSELECT文From複数行() ' --------------------------------------------------------------------------------------------------------- ' SQL文の発行 ' --------------------------------------------------------------------------------------------------------- Dim txtCountQuery As String txtCountQuery = obj試験データテーブル(i).createCount文(txtQuery) ' log("発行するSQL:" & txtCountQuery) Set rs = oraconn.Execute(txtCountQuery) obj試験データテーブル(i).setDBCount結果 (rs.Fields("COUNT")) rs.Close Set rs = Nothing Set rs = oraconn.Execute(txtQuery) obj試験データテーブル(i).copy枠Toクリップボード With wb実行結果.ActiveSheet.Range("A" & lng出力最終行) .PasteSpecial ' データ行をコピー End With With wb実行結果.ActiveSheet.Range("F" & lng出力最終行) .ClearComments .AddComment ("-- 結果取得時のSQL" & vbCrLf _ & txtQuery) ' テーブル論理名のセルにデータ取得に使用したSQLをコメントで残す .Comment.Shape.TextFrame.AutoSize = True Dim lngデータ行数 As Long If obj試験データテーブル(i).getDBCount結果 = 0 Then lngデータ行数 = 1 Else lngデータ行数 = obj試験データテーブル(i).getDBCount結果 End If ' 件数の情報を書き込み .Value = "=COUNTA(B" & lng出力最終行 + cnstヘッダ行数 & ":B" & lng出力最終行 + cnstヘッダ行数 + lngデータ行数 & ")" End With lng出力最終行 = lng出力最終行 + cnstヘッダ行数 ' 行のクリア(記入された文字+セルの背景色) wb実行結果.ActiveSheet.Rows(lng出力最終行).ClearContents With wb実行結果.ActiveSheet.Rows(lng出力最終行).Interior .Pattern = xlNone .TintAndShade = 0 .PatternTintAndShade = 0 End With If obj試験データテーブル(i).getDBCount結果 > 0 Then ' 行の罫線をコピー wb実行結果.ActiveSheet.Rows(lng出力最終行).Copy wb実行結果.ActiveSheet.Rows(lng出力最終行 & ":" _ & lng出力最終行 + obj試験データテーブル(i).getDBCount結果() - 1).PasteSpecial Dim var取得結果 As Variant ReDim var取得結果( _ 1 To obj試験データテーブル(i).getDBCount結果, _ 1 To rs.Fields.Count) Dim j As Long For j = 1 To UBound(var取得結果) If rs.EOF Then Exit For End If Dim k As Long For k = 1 To rs.Fields.Count var取得結果(j, k) = rs.Fields(k - 1) Next k rs.MoveNext Next j With wb実行結果.ActiveSheet .Range(.Cells(lng出力最終行, 2), _ .Cells(lng出力最終行 + UBound(var取得結果) - 1, UBound(var取得結果, 2) + 1)) = var取得結果 End With lng出力最終行 = lng出力最終行 + obj試験データテーブル(i).getDBCount結果() + 1 Else lng出力最終行 = lng出力最終行 + 2 ' 空枠+余白で2行 End If continue: Next i End With ' レコードセットをクローズする rs.Close Set rs = Nothing Set executeSQL = wb実行結果 End Function ' ********************************************************************************************************************* ' 機能:対象シートのINSERT文生成 ' ********************************************************************************************************************* ' Public Function 対象シートINSERT文作成(ByRef obj対象シート As Worksheet) As String If obj対象シート.Range("A1") <> "凡例" Then Exit Function End If Dim obj試験データテーブル() As cls試験データテーブル obj試験データテーブル = getテーブル座標情報 Dim txt結果 As String Dim i As Long For i = LBound(obj試験データテーブル) To UBound(obj試験データテーブル) txt結果 = txt結果 & obj試験データテーブル(i).createInsert文(obj対象シート) continue: Next i 対象シートINSERT文作成 = txt結果 End Function ' ********************************************************************************************************************* ' 機能:テーブルのグループごとの表示/非表示を制御する ' ********************************************************************************************************************* ' Public Sub 表示非表示の切替(Optional ByVal txtテーブル名 As String = "*マスタ") Dim varテーブル座標情報 As Variant varテーブル座標情報 = getテーブル座標情報 Dim i As Long ActiveSheet.Outline.ShowLevels RowLevels:=2 ActiveSheet.Rows.Ungroup For i = LBound(varテーブル座標情報) To UBound(varテーブル座標情報) If Not ActiveSheet.Range("A" & varテーブル座標情報(i, 1)) Like txtテーブル名 Then Range(Cells(varテーブル座標情報(i, 1) + 1, 1), Cells(varテーブル座標情報(i, 3), 1)).Rows.Group End If Next i ActivceSheet.Outline.ShowLevels RowLevels:=1 For i = LBound(varテーブル座標情報) To UBound(varテーブル座標情報) If ActiveSheet.Range("A" & varテーブル座標情報(i, 1)) Like txtテーブル名 Then Range(Cells(varテーブル座標情報(i, 1) + 1, 1), Cells(varテーブル座標情報(i, 3), 1)).Row.Group End If Next i End Sub ' ********************************************************************************************************************* ' 機能:引数で指定されたブックの後方2シートを比較し、差分に関する情報を後方のシートに付与する。 ' ********************************************************************************************************************* ' Public Sub edit実行結果差分(ByRef wb引数実行結果 As Workbook) wb引数実行結果.Activate Dim ws実行前, ws実行後 As Worksheet Set ws実行前 = wb引数実行結果.Sheets(wb引数実行結果.Sheets.Count - 1) Set ws実行後 = wb引数実行結果.Sheets(wb引数実行結果, Sheets, Count) Dim obj実行前データテーブル() As cls試験データテーブル Dim obj実行後データテーブル() As cls試験データテーブル ws実行前.Activate obj実行前データテーブル = getテーブル座標情報() ws実行後.Activate obj実行後データテーブル = getテーブル座標情報() Dim i, j As Long i = UBound(obj実行後データテーブル) j = UBound(obj実行前データテーブル) ' 実行後を軸に、実行前とのマッチングを行っていく Do While (UBound(obj実行後データテーブル) <= i Or LBound(obj実行前データテーブル) <= j) If obj実行後データテーブル(i).getテーブル物理名 <> obj実行前データテーブル(j).getテーブル物理名 Then j = j - 1 If j < UBound(obj実行前データテーブル) Then Exit Sub ' 実行前テーブルが存在しなくなった場合、終了 End If Else Call compareテーブル(obj実行前データテーブル(j), obj実行後データテーブル(i)) i = i - 1 j = j - 1 End If Loop End Sub ' ===================================================================================================================== ' Privateメソッド ' ===================================================================================================================== ' ' ********************************************************************************************************************* ' 機能:テーブル内容の比較を行う ' ********************************************************************************************************************* ' Private Sub compareテーブル( _ ByRef obj実行前データテーブル As cls試験データテーブル, ByRef obj実行後データテーブル As cls試験データテーブル) If obj実行前データテーブル.get件数() = 0 And obj実行後データテーブル.get件数() = 0 Then Exit Sub ' 両方0件の場合、何もしない End If Dim i, j As Long With obj実行後データテーブル i = .データ終了行 j = obj実行前データテーブル.データ終了行 Do While (i >= .データ開始行 Or j >= obj実行前データテーブル.データ開始行) ' データがない行を読み飛ばす If .get主キー項目連結文字列(i) = "" Then i = i - 1 GoTo continue ElseIf obj実行前データテーブル.get主キー項目連結文字列(j) = "" Then j = j - 1 GoTo continue End If ' いずれかのデータを読み切っている場合 If j < obj実行前データテーブル.データ開始行 Then Call log差異("読切追加", j, obj実行前データテーブル, i, obj実行後データテーブル) obj実行後データテーブル.edit選択行強調 (i) With .対象シート.Cells(i, 1) .AddComment ("■追加") .Comment.Shape.TextFrame.AutoSize = True End With i = i - 1 GoTo continue ElseIf i < .データ開始行 Then Call log差異("読切削除", j, obj実行前データテーブル, i, obj実行後データテーブル) obj実行後データテーブル.add空行 (obj実行後データテーブル.データ開始行) obj実行後データテーブル.edit選択行網掛 (obj実行後データテーブル.データ開始行) With .対象シート.Cells(obj実行後データテーブル.データ開始行, 1) .AddComment ("■削除" & vbCrLf _ & Join(obj実行前データテーブル.get主キー(), " ") & vbLf _ & Join(obj実行前データテーブル.get主キー(j), " ")) .Comment.Shape.TextFrame.AutoSize = True End With j = j - 1 GoTo continue End If ' まだ、いずれのデータも残っている場合 If .get主キー項目連結文字列(i) = obj実行前データテーブル.get主キー項目連結文字列(j) Then Call log差異("比較一致", j, obj実行前データテーブル, i, obj実行後データテーブル) Call compareレコード(obj実行前データテーブル, obj実行前データテーブル, j, i) i = i - 1 j = j - 1 ElseIf StrComp(.get主キー項目連結文字列(i), obj実行前データテーブル.get主キー項目連結文字列(j), _ vbBinaryCompare) > 0 Then Call log差異("比較追加", j, obj実行前データテーブル, i, obj実行後データテーブル) obj実行後データテーブル.edit選択行強調 (i) With .対象シート.Cells(i, 1) .AddComment ("■追加") .Comment.Shape.TextFrame.AutoSize = True End With i = i - 1 Else Call log差異("比較削除", j, obj実行前データテーブル, i, obj実行後データテーブル) obj実行後データテーブル.add空行 (i + 1) obj実行後データテーブル.edit選択行網掛 (i + 1) With .対象シート.Cells(i + 1, 1) .AddComment ("■削除" & vbCrLf _ & Join(obj実行前データテーブル.get主キー(), " ") & vbCrLf _ & Join(obj実行前データテーブル.get主キー(), " ")) .Comment.Shape.TextFrame.AutoSize = True End With j = j - 1 End If continue: Loop End With End Sub ' ********************************************************************************************************************* ' 機能:デバッグ用の差異情報出力メソッド ' ********************************************************************************************************************* ' Private Sub compareレコード( _ ByRef obj実行前データテーブル As cls試験データテーブル, _ ByRef obj実行後データテーブル As cls試験データテーブル, _ ByVal lng実行前対象行 As Long, ByVal lng実行後対象行 As Long) Dim txtコメント文字列 As String Dim txt変更前, txt変更後 As String Dim i As Long For i = 2 To obj実行前データテーブル.カラム終了列 txt変更前 = obj実行前データテーブル.対象シート.Cells(lng実行前対象行, i) txt変更後 = obj実行後データテーブル.対象シート.Cells(lng実行後対象行, i) If txt変更前 <> txt変更後 Then Call obj実行後データテーブル.edit変更強調色(obj実行後データテーブル.Cells(lng実行後対象行, i)) txtコメント文字列 = txtコメント文字列 & vbCrLf _ & obj実行前データテーブル.getカラム論理名(i) & ":" & txt変更前 & " → " & txt変更後 End If Next i If txtコメント文字列 <> "" Then With obj実行後データテーブル.対象シート.Cells(lng実行後対象行, 1) .AddComment ("■更新" & txtコメント文字列) .Comment.Shape.TextFrame.AutoSize = True End With End If End Sub ' ********************************************************************************************************************* ' 機能:デバッグ用の差異情報出力メソッド ' ********************************************************************************************************************* ' Private Sub log差異(ByVal txtメッセージ As String, _ ByVal lng変更前対象行 As Long, ByRef obj実行前データテーブル As cls試験データテーブル, _ ByVal lng変更後行番号 As Long, ByRef obj実行後データテーブル As cls試験データテーブル) log obj実行前データテーブル.getカラム論理名 & vbTab & txtメッセージ _ & vbTab _ & "変更前" & vbTab & lng変更前行番号 & "行目" & vbTab _ & obj実行後データテーブル.get主キー項目連結文字列(lng変更前対象行) _ & vbTab _ & "変更後" & vbTab & lng変更後行番号 & "行目" & vbTab _ & obj実行後データテーブル.get主キー項目連結文字列(lng変更後行番号) End Sub ' ********************************************************************************************************************* ' 機能:テーブルごとの座標情報を返却する ' ********************************************************************************************************************* ' Private Function getテーブル座標情報() As cls試験データテーブル() Dim lng最終行, lng最終列 As Long Dim varテーブル座標情報ワーク As Variant With ActiveSheet.UsedRange lng最終行 = .Find("*", , xlFormulas, , xlByRows, xlPrevious).Row lng最終列 = .Find("*", , xlFormulas, , xlByColumns, xlPrevious).Column End With varテーブル座標情報ワーク = Range("A" & cnst試験データ開始行 & ":B" & lng最終行 + cnstヘッダ行数) Dim lngテーブル数 As Long lngテーブル数 = WorksheetFunction.CountA(Range("A" & cnst試験データ開始行 & ":A" & lng最終行)) Dim obj試験データテーブル() As cls試験データテーブル ReDim obj試験データテーブル(1 To lngテーブル数) Dim i, index As Long: index = 0 For i = 1 To UBound(varテーブル座標情報ワーク) ' テーブル名の列に値が設定されている場合 If varテーブル座標情報ワーク(i, 1) <> "" Then index = index + 1 Set obj試験データテーブル(index) = New cls試験データテーブル ' 実際の行番号を設定するため開始行分行数を加算 Set obj試験データテーブル(index).対象シート = ActiveSheet obj試験データテーブル(index).setテーブル名記載行 (cnst試験データ開始行 + i - 1) If index > 1 Then ' テーブル名が見つかった場合、その2セル上を前テーブルの終了行とみなす obj試験データテーブル(index - 1).setデータ終了行 (obj試験データテーブル(index).getテーブル名記載行 - 2) End If End If Next i If index > 0 Then ' 最後のテーブルは、最終行の3行後を最終行とみなす obj試験データテーブル(index).setデータ終了行 (lng最終行 + 3) End If getテーブル座標情報 = obj試験データテーブル End Function
実装処理
Option Explicit ' --------------------------------------------------------------------------------------------------------------------- ' 定数(共通) ' --------------------------------------------------------------------------------------------------------------------- ' タイトル名(共通) Public Const TITLE_NAME_BY_TARGET_DIR = "▼ファイル" Public Const TITLE_NAME_BY_DO_SUB_DIR = "▼配下のディレクトリも対象" ' 雛形シートコピー用(共通) Public Const TEMPLATE_SHEET_NAME = "雛形" Public Const RESULT_SHEET_NAME = "処理結果" ' 対象の拡張子 Public Const FILE_EXTENSION = "xls,xlsx,xlsm" ' 処理結果シートデータ貼付け部の列数 Private Const RESULT_COL_LENGTH = 6 ' --------------------------------------------------------------------------------------------------------------------- ' 定数(個別) ' --------------------------------------------------------------------------------------------------------------------- ' タイトル文字列(対象シート固有) Private Const TITLE_NAME_BY_SEARCH_WORD = "▼検索ワード" ' 検索文言リスト Private varSearchArgList As Variant ' 処理した件数 Dim lngResultCount As Long ' ##################################################################################################################### ' # ' # テンプレートメソッド(テンプレート処理から呼び出されるメソッド) ' # ' # 1. 全体前処理() 処理実行前に1度だけ実行したい処理を実装する ' # 2. ブックOPEN後処理() 検出されたファイルのブックごとに行いたい処理を実装する ' # (シート毎の処理呼び出しが不要かの判定値(boolean)を返却する) ' # 3. シート毎処理() 検出されたファイルの1シートごとに行いたい処理を実装する ' # 4. ブックCLOSE前処理() 検出されたファイルのブックごとに行いたい後処理を実装する ' # 5. 実行結果内容編集処理() 実行結果について、ファイルに出力する前に編集したい場合に実装する(重複の削除、ソート等) ' # 6. 実行結果書式編集処理() ファイルに出力した後の実行結果を編集したい場合に実装する(ハイパーリンクの設定等) ' # 7. 全体後処理() 処理実行後に1度だけ実行したい処理を実装する ' # ' ##################################################################################################################### ' ' ********************************************************************************************************************* ' 機能 :固有処理側の前処理 ' ********************************************************************************************************************* ' Function 全体前処理(targetSheet As Worksheet) ' ----------------------------------------------------------------------------------------------------------------- ' 初期化処理 ' ----------------------------------------------------------------------------------------------------------------- ' 処理した件数の初期化 ' resultCount = 0 ' ----------------------------------------------------------------------------------------------------------------- ' 前処理 ' ----------------------------------------------------------------------------------------------------------------- ' 処理対象の検索文言リストを取得する。 ' 固有処理(マクロの呼び出し元)側のパス情報を取得する。 varSearchArgList = タイトル名指定でリスト値を取得(TITLE_NAME_BY_SEARCH_WORD, targetSheet) End Function ' ********************************************************************************************************************* ' 機能 :検出されたファイルのブックごとに行いたい処理を実装する(シート毎の処理呼び出しが不要かの判定値(boolean)を返却する) ' ********************************************************************************************************************* ' Function ブックOPEN後処理(fileName As Variant, targetWB As Workbook, ByRef results() As Variant) As Boolean End Function ' ********************************************************************************************************************* ' 機能 :検出されたファイルの1シートごとに行いたい処理を実装する ' ********************************************************************************************************************* ' Function シート毎処理(fileName As Variant, targetSheet As Worksheet, ByRef results() As Variant) Dim FSO Set FSO = CreateObject("Scripting.FileSystemObject") Dim searchArg As Variant Dim targetWB As Workbook Dim ShapesInfoList As Variant Dim ShapesInf As Variant ' ----------------------------------------------------------------------------------------------------------------- ' 処理 ' ----------------------------------------------------------------------------------------------------------------- ' 指定された検索文言リストの文字列の検索結果を収集する。 ' 対象シートの検索結果を「FoundAddr」に格納する。 Dim firstAddress As String Dim FoundCell As Range Dim lngResultCount As Long ' 結果件数 ' 検索文言リスト分ループ For Each searchArg In varSearchArgList ' 検索文言がない場合、次の検索文言を処理する If "" = searchArg Then GoTo ContinueBySearchArg End If ' <セルの検索> Set FoundCell = targetSheet.UsedRange.Find(what:=searchArg, LookIn:=xlValues, _ LookAt:=xlPart, MatchCase:=False, MatchByte:=False) ' セルへの検索結果がない場合 If FoundCell Is Nothing Then ' 検索結果がなかった場合次の検索文言を処理する GoTo GotoCellSearchEnd End If firstAddress = FoundCell.Address ' 検索結果のアドレスを配列に格納 Do ' 結果を格納する Call reDimResult(RESULT_COL_LENGTH, results) ' 結果保持の配列作成 lngResultCount = UBound(results, 2) results(0, lngResultCount) = searchArg ' 検索文言 results(1, lngResultCount) = FSO.GetParentFolderName(fileName) ' フォルダ名 results(2, lngResultCount) = FSO.GetFileName(fileName) ' ファイル名 results(3, lngResultCount) = targetSheet.Name ' シート名 results(4, lngResultCount) = FoundCell.Address(False, False) ' 座標 results(5, lngResultCount) = "セル" ' セル/オートシェイプ results(6, lngResultCount) = FoundCell.Value ' 文字列 Set FoundCell = targetSheet.UsedRange.FindNext(After:=FoundCell) Loop Until FoundCell.Address = firstAddress GotoCellSearchEnd: ' <オートシェイプの検索> ShapesInfoList = getShapesProperty(targetSheet) Dim i As Integer Dim textValue As Variant i = 0 ' 検索文言リスト分ループ If Not IsEmpty(ShapesInfoList) Then For i = LBound(ShapesInfoList) To UBound(ShapesInfoList) textValue = ShapesInfoList(i, 2) If Not IsEmpty(textValue) And InStr(textValue, searchArg) Then lngResultCount = UBound(results, 2) ' 結果を格納する Call reDimResult(RESULT_COL_LENGTH, results) ' 結果保持の配列作成 results(0, lngResultCount) = searchArg ' 検索文言 results(1, lngResultCount) = FSO.GetParentFolderName(fileName) ' フォルダ名 results(2, lngResultCount) = FSO.GetFileName(fileName) ' ファイル名 results(3, lngResultCount) = targetSheet.Name ' シート名 results(4, lngResultCount) = ShapesInfoList(i, 7) ' 座標 results(5, lngResultCount) = "オートシェイプ" ' セル/オートシェイプ results(6, lngResultCount) = textValue ' 文字列 End If Next i End If ContinueBySearchArg: Next End Function ' ********************************************************************************************************************* ' 機能 :検出されたファイルのブックごとに行いたい後処理を実装する ' ********************************************************************************************************************* ' Function ブックCLOSE前処理(fileName As Variant, targetWB As Workbook, ByRef results() As Variant) As Long End Function ' ********************************************************************************************************************* ' 機能 :実行結果について、ファイルに出力する前に編集したい場合に実装する(重複の削除、ソート等) ' ********************************************************************************************************************* ' Function 実行結果内容編集処理(ByRef var変換元() As Variant) As Variant End Function ' ********************************************************************************************************************* ' 機能 :ファイルに出力した後の実行結果を編集したい場合に実装する(ハイパーリンクの設定等) ' ********************************************************************************************************************* ' Sub 実行結果書式編集処理(ByRef targetSheet As Worksheet) Dim i, MaxRow, MaxCol As Long With targetSheet MaxRow = .UsedRange.Find("*", , xlFormulas, , xlByRows, xlPrevious).Row MaxCol = .UsedRange.Find("*", , xlFormulas, , xlByColumns, xlPrevious).Column ' 書式コピー .Range(Cells(2, 1), Cells(2, MaxCol)).Copy .Range(Cells(2 + 1, 1), Cells(MaxRow, MaxCol)).PasteSpecial (xlPasteFormats) For i = 2 To MaxRow ' ハイパーリンク設定 Dim strHyperLink As String strHyperLink = editHYPERLINK数式(.Cells(i, 2), .Cells(i, 3), .Cells(i, 4), .Cells(i, 5)) .Range(.Cells(i, 5), .Cells(i, 5)).Value = strHyperLink ' 赤文字 Call 検索該当文字の赤太文字化(.Range(Cells(i, 7), Cells(i, 7)), Cells(i, 1)) Next End With End Sub ' ********************************************************************************************************************* ' 機能 :処理実行後に1度だけ実行したい処理を実装する ' ********************************************************************************************************************* ' Function 全体後処理(targetSheet As Worksheet) End Function ' ##################################################################################################################### ' # ' # テンプレートメソッド以外のメソッド ' # ' ##################################################################################################################### ' ' なし
テンプレート処理
Option Explicit ' --------------------------------------------------------------------------------------------------------------------- ' 定数 ' --------------------------------------------------------------------------------------------------------------------- ' なし ' ********************************************************************************************************************* ' * 機能 :マクロ呼び出し時(シートからの指定用) ' ********************************************************************************************************************* Sub マクロ開始() Call init開始時刻 Dim wsMainSheet As Worksheet Dim fileCheck As Long ' タイトル名に対するリストの情報(Range情報) Dim currentDirPathRangeList As Range, currentDirPathRange As Range Dim subDirCheckBoxRangeList As Range, subDirCheckBoxRange As Range ' 処理対象のファイル名一覧(フルパス&ファイル名) Dim fileNames() As String ' ----------------------------------------------------------------------------------------------------------------- ' 初期化処理 ' ----------------------------------------------------------------------------------------------------------------- ' 処理対象の拡張子を設定する。 Dim fileExtention As Variant fileExtention = Split(FILE_EXTENSION, ",") ' 固有処理(マクロ呼び出し元)側のシート情報を取得する。 ' Set wsMainSheet = MainSheet Set wsMainSheet = ActiveSheet ' 固有処理(マクロ呼び出し元)側のパス情報を取得する。 Set currentDirPathRangeList = タイトル名指定でリスト値のRange情報を取得(TITLE_NAME_BY_TARGET_DIR, wsMainSheet) Set subDirCheckBoxRangeList = タイトル名指定でリスト値のRange情報を取得(TITLE_NAME_BY_DO_SUB_DIR, wsMainSheet) ' ★ConcreateProcess側の処理の呼び出し(呼び出し先のProcedure側ではツールごとの固有の実装を行う) Call 全体前処理(wsMainSheet) ' ----------------------------------------------------------------------------------------------------------------- ' パスの存在チェック ' ----------------------------------------------------------------------------------------------------------------- With wsMainSheet Dim i As Long i = 0 ' 対象ディレクトリ分ループ If Not (currentDirPathRangeList Is Nothing) Then For Each currentDirPathRange In currentDirPathRangeList ' ディレクトリまたは、ファイルの存在チェック fileCheck = isDirectoryExist(CStr(currentDirPathRange.Value)) If 0 > fileCheck Then MsgBox "以下のパスは存在しません。" + Chr(10) + "「" + currentDirPathRange.Value + "」" End End If i = i + 1 Next End If End With ' ----------------------------------------------------------------------------------------------------------------- ' ファイル名の収集 ' ----------------------------------------------------------------------------------------------------------------- Call setステータスバー("対象ファイル集計中...") With ActiveSheet i = 1 '対象ディレクトリ分ループ If Not (currentDirPathRangeList Is Nothing) Then For Each currentDirPathRange In currentDirPathRangeList '指定の値がファイルの場合、その値をリストに追加し、ディレクトリの場合は、ファイル名の一覧を動的に取得して追加する。 fileCheck = isDirectoryExist(CStr(currentDirPathRange.Value)) If 2 = fileCheck Then ' 指定の値がファイルだった場合、その値をリストに追加 ' フルパス&ファイル名を追加格納。 Call 一次配列に値を追加(fileNames, CStr(currentDirPathRange.Value)) Else ' <オートシェイプ情報の取得> Dim shapesCount As Long Dim checkBoxChecked As Variant Dim topLeftCellRow As Variant, topLeftCellColumn As Variant ' オートシェイプ(チェックボックス)情報を取得。 Dim ShapesInfoList As Variant ShapesInfoList = getShapesProperty(wsMainSheet, msoFormControl, xlCheckBox) ' 対象セル行のチェックボックスのチェック状態を取得(boolean形式で) checkBoxChecked = False If IsArrayEx(ShapesInfoList) > 0 Then For shapesCount = LBound(ShapesInfoList) To UBound(ShapesInfoList) topLeftCellRow = ShapesInfoList(shapesCount, 8) topLeftCellColumn = ShapesInfoList(shapesCount, 9) ' 取得したチェックボックスが以下の条件に一致した場合、対象と判断する。 ' ・チェックボックスの行が、処理中の対象ディレクトリの行と一致。 ' ・チェックボックスの列が、タイトルの列と一致。 If Not IsEmpty(topLeftCellRow) And topLeftCellRow = currentDirPathRange.Row _ And topLeftCellColumn = subDirCheckBoxRangeList.Item(0).Column Then ' チェックボックス値を取得する。 If 1 = ShapesInfoList(shapesCount, 2) Then checkBoxChecked = True End If Exit For End If Next shapesCount End If ' 現在のディレクトリ配下のファイル名を取得 Call doRepeat(currentDirPathRange, fileExtention, fileNames, checkBoxChecked) End If i = i + 1 Next End If End With ' ----------------------------------------------------------------------------------------------------------------- ' ファイル処理メソッドの呼び出し ' ----------------------------------------------------------------------------------------------------------------- Call ファイル処理(fileNames) ' ★実装処理側の処理の呼び出し(呼び出し先のProcedure側ではツールごとの固有の実装を行う) Call 全体後処理(wsMainSheet) MsgBox "処理が終了しました。(処理時間:" & get処理時刻() & ")" End Sub ' ********************************************************************************************************************* ' * 機能 :対象ファイルの処理を行う。 ' * 引数 :varArray 配列 ' * 戻り値:判定結果(1:配列/0:空の配列/-1:配列ではない) ' ********************************************************************************************************************* ' Function ファイル処理(fileNames() As String) ' ファイル名の一覧が空だった場合、当Functionを中断する。 If 1 > IsArrayEx(fileNames) Then MsgBox "処理対象ファイルが存在しません。" Exit Function End If Dim FSO Set FSO = CreateObject("Scripting.FileSystemObject") Dim fileName As Variant Dim targetWB As Workbook Dim targetSheet As Worksheet Dim index As Long, total As Long Dim defaultSaveFormat As Long defaultSaveFormat = Application.defaultSaveFormat ' シート毎の処理呼び出し不要フラグ Dim unDealTargetSheetFlag As Boolean ' 処理結果保持用 Dim results() As Variant index = 1 total = UBound(fileNames) + 1 Application.DisplayAlerts = False ' ファイルを開く際の警告を無効 Application.ScreenUpdating = False ' 画面表示更新を無効 For Each fileName In fileNames ' ------------------------------------------------------------------------------------------------------------- ' 対象ブックを開いて、全シート分の処理を行う。 ' ------------------------------------------------------------------------------------------------------------- Call setステータスバー("(" & index & "/" & total & ")" & FSO.GetFileName(fileName)) index = index + 1 Set targetWB = Workbooks.Open(fileName, UpdateLinks:=0, IgnoreReadOnlyRecommended:=False) ' ★実装処理側の処理の呼び出し(呼び出し先のProcedure側ではツールごとの固有の実装を行う) unDealTargetSheetFlag = ブックOPEN後処理(fileName, targetWB, results) If False = unDealTargetSheetFlag Then Dim i As Integer For i = 1 To targetWB.Worksheets.Count ' シートの数分ループする Set targetSheet = targetWB.Worksheets(i) ' ★実装処理側の処理の呼び出し(呼び出し先のProcedure側ではツールごとの固有の実装を行う) Call シート毎処理(fileName, targetSheet, results) Next i End If Dim ファイルCLOSE方法区分値 As Long ' ★実装処理側の処理の呼び出し(呼び出し先のProcedure側ではツールごとの固有の実装を行う) ファイルCLOSE方法区分値 = ブックCLOSE前処理(fileName, targetWB, results) If ファイルCLOSE方法区分値 = ファイルCLOSE方法区分.保存しないで閉じる Then targetWB.Close ElseIf ファイルCLOSE方法区分値 = ファイルCLOSE方法区分.保存して閉じる Then targetWB.Save targetWB.Close ElseIf ファイルCLOSE方法区分値 = ファイルCLOSE方法区分.保存しないで閉じない Then ElseIf ファイルCLOSE方法区分値 = ファイルCLOSE方法区分.保存して閉じない Then targetWB.Save ElseIf ファイルCLOSE方法区分値 = ファイルCLOSE方法区分.処理中断 Then End End If Next ' ★実装処理側の処理の呼び出し(呼び出し先のProcedure側ではツールごとの固有の実装を行う) ' 実行結果の編集(結果のマージ、並び替え、フィルタリング当) Call 実行結果内容編集処理(results) If Not Not results Then If UBound(results, 2) <> 0 Then ' ファイルの保存形式をexcel2007形式(.xlsx)に変更 Application.defaultSaveFormat = xlOpenXMLWorkbook Set targetWB = Workbooks.Add ' 当ブックにシート「雛形」が用意されている場合、指定ブックの先頭にコピーした後、 ' シート名を「処理結果」に変更する。(ない場合は新規作成ブックのsheet1を利用) Call 雛形シートコピー(targetWB) ' 結果貼り付け行の取得。 ' A列に値が設定されている行を、表題欄としてその行数を取得する Dim MaxRow As Integer With targetWB.ActiveSheet.UsedRange MaxRow = .Find("*", , xlFormulas, , xlByRows, xlPrevious).Row End With ' 結果貼り付け行の設定。 MaxRow = MaxRow + 1 ' 結果貼り付け targetWB.ActiveSheet.Range(Cells(MaxRow, 1), Cells(UBound(results, 2) + 2, UBound(results) + 1)) = 二次元配列行列逆転(results) Dim MaxCol As Integer ' 書式コピー With targetWB.ActiveSheet MaxRow = .UsedRange.Find("*", , xlFormulas, xlByRows, xlPrevious).Row MaxCol = .UsedRange.Find("*", , xlFormulas, xlByColumns, xlPrevious).Column .Range(.Cells(2, 1), .Cells(2, MaxCol)).Copy .Range(.Cells(2 + 1, 1), .Cells(MaxRow, MaxCol)).PasteSpecial (xlPasteFormats) End With ' ★実装処理側の処理の呼び出し(呼び出し先のProcedure側ではツールごとの固有の実装を行う) Call 実行結果書式編集処理(targetWB.ActiveSheet) ' "A1"を選択状態にする targetWB.ActiveSheet.Cells(1, 1).Select ' シート名「処理結果」以外のシートを削除する Call 不要シート削除(targetWB, RESULT_SHEET_NAME) Else MsgBox "処理結果は0件です。" End If Else MsgBox "処理結果は0件です。" End If Application.DisplayAlerts = True Application.ScreenUpdating = True Application.StatusBar = False ' ファイルの保存形式を元の状態に戻す Application.defaultSaveFormat = defaultSaveFormat If Not Not results Then If UBound(results, 2) <> 0 Then targetWB.Activate End If End If End Function ' ********************************************************************************************************************* ' * 機能 :当ブックのシート「雛形」を指定ブックの先頭にコピーした後、 ' * シート名を「処理結果」に変更する ' ********************************************************************************************************************* ' Sub 雛形シートコピー(targetWB As Workbook) Dim myWorkBook As String Dim newWorkBook As String Dim targetSheet As Worksheet Dim sheetName As String ' マクロを実行中のブック名を取得 myWorkBook = ThisWorkbook.Name ' 新規ブック名を取得 newWorkBook = targetWB.Name ' マクロ実行時のブックをアクティブにする Workbooks(myWorkBook).Activate ' シート「雛形」があった場合、指定ブックにコピー(一番前に挿入)する Dim i As Integer For i = 1 To Workbooks(myWorkBook).Worksheets.Count ' シートの数分ループする Set targetSheet = Workbooks(myWorkBook).Worksheets(i) If TEMPLATE_SHEET_NAME = targetSheet.Name Then Workbooks(myWorkBook).Sheets(TEMPLATE_SHEET_NAME).Copy _ Before:=Workbooks(newWorkBook).Sheets(1) End If Next i ' マクロを実行中のブックをアクティブにする Workbooks(targetWB.Name).Sheets(TEMPLATE_SHEET_NAME).Activate ' シート名を「処理結果」に変更する Workbooks(targetWB.Name).Sheets(TEMPLATE_SHEET_NAME).Name = RESULT_SHEET_NAME End Sub
Util
Attribute VB_Name = "Util" Option Explicit ' --------------------------------------------------------------------------------------------------------------------- ' 定数 ' --------------------------------------------------------------------------------------------------------------------- Public Const TITLE_NAME_PREFIX = "▼" ' --------------------------------------------------------------------------------------------------------------------- ' 変数 ' --------------------------------------------------------------------------------------------------------------------- Dim var開始時刻 As Variant ' ##################################################################################################################### ' # ' # ログ系ユーティリティ ' # ' ##################################################################################################################### Sub log(ByVal strメッセージ As String) Debug.Print Format(Now(), "HH:mm:ss ") & strメッセージ End Sub ' ##################################################################################################################### ' # ' # ステータスバー操作系ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' * 機能 :ステータスバーに表示する処理時間を初期化する ' ********************************************************************************************************************* ' Sub init開始時刻() var開始時刻 = Now() End Sub ' ********************************************************************************************************************* ' * 機能 :処理時間の開始時刻を取得する ' ********************************************************************************************************************* ' Function get開始時刻() get開始時刻 = var開始時刻 End Function ' ********************************************************************************************************************* ' * 機能 :処理時間を HH:mm:ss 形式で取得する ' ********************************************************************************************************************* ' Function get処理時刻() get処理時刻 = Format(Now() - var開始時刻, "HH:mm:ss") End Function ' ********************************************************************************************************************* ' * 機能 :ステータスバーに経過時間付でメッセージを表示する ' ********************************************************************************************************************* ' Sub setステータスバー(ByVal strメッセージ As String) If IsEmpty(var開始時刻) Then var開始時刻 = Now() End If Application.StatusBar = get処理時刻() & " " & strメッセージ End Sub ' ##################################################################################################################### ' # ' # ブック、シート操作系ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' * 機能 :引数で渡されたシート名以外のシートを削除する ' ********************************************************************************************************************* ' ' Function 不要シート削除(対象ブック情報 As Workbook, ByVal 残すシート名 As String) Dim 前状態 As Boolean 前状態 = Application.DisplayAlerts Application.DisplayAlerts = False Dim ws As Worksheet For Each ws In 対象ブック情報.Worksheets If ws.Name <> 残すシート名 Then Worksheets(ws.Name).Delete End If Next ws Application.DisplayAlerts = 前状態 End Function ' ##################################################################################################################### ' # ' # ダイアログ操作系ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' * 機能 :処理続行 or 中止確認ダイアログを表示する ' ********************************************************************************************************************* ' Function 処理続行判断(message As String) Dim rc As VbMsgBoxResult rc = MsgBox(message + Chr(10) + "処理を続行しますか?", vbYesNo, vbQuestion) If rc = vbYes Then MsgBox "処理を続けます", vbInformation Else MsgBox "処理を中止しました。", vbCritical ' マクロの実行中止 End End If ' ********************************************************************************************************************* ' * 機能 :確認ダイアログを表示 ' ********************************************************************************************************************* ' Function 確認ダイアログ表示(messages() As String, Optional ByVal 処理続行確認ダイアログ表示フラグ As Boolean = True) As Long Dim dispMessage, message As Variant For Each message In messages dispMessage = dispMessage + message + Chr(10) Next Dim rc As VbMsgBoxResult rc = MsgBox(dispMessage, vbYesNoCancel + vbQuestion) If rc = vbCancel Then MsgBox "処理を中止しました", vbCritical ' マクロの実行中断 End Else If True = 処理続行確認ダイアログ表示フラグ Then MsgBox "処理を続けます", vbInformation End If End If 確認ダイアログ表示 = rc End Function ' ##################################################################################################################### ' # ' # オートシェイプ操作系ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' 機能名:対象シート上にあるオブジェクトおnプロパティを取得する ' 戻り :getShapesProperty as String(2, n) ' (0, n) type ' (1, n) name ' (2, n) TextFrame.Characters.text ' (3, n) Left ' (4, n) Top ' (5, n) Width ' (6, n) Height ' (7, n) TopLeftCell.Address(False, False) ' (8, n) TopLeftCell.row ' (9, n) TopLeftCell.Column ' (10, n) BottomRightCell.Address(False, False) ' (11, n) BottomRightCell.row ' (12, n) BottomRightCell.Column ' ' ********************************************************************************************************************* ' Function getShapesProperty(ByRef targetSheet As Worksheet, Optional ByVal objType As Long = -999, Optional ByVal formCtlType As Long = -999) As Variant Dim ret As Variant Dim i As Long Dim obj As Variant ' 配列の作成。 i = 0 For Each obj In targetSheet.Shapes ' FORMコントロールの場合 If obj.Type = objType Then ' 渡されたフォームコントロールタイプが一致した場合、カウントアップ If obj.FormControlType = formCtlType Then i = i + 1 End If ' 指定なし又は、それ以外のオートシェイプ ElseIf objType = -999 Or obj.Type = objType Then i = i + 1 End If Next ' 対象のオートシェイプがみつかった場合のみ、そのオブジェクトの格納を行う。 If 0 <> i Then ReDim ret(i - 1, 12) ' 配列の作成 i = 0 ' オブジェクト情報の設定 For Each obj In targetSheet.Shapes ' formコントロールの場合 If obj.Type = objType Then ' 渡されたフォームコrントロールタイプが一致した場合、値を取得する。 If obj.FormControlType = formCtlType Then ret(i, 0) = obj.Type ret(i, 1) = obj.AlternativeText ' TextFrameプロパティが使用できない(レイアウト枠がない)オブジェクトは除外 On Error Resume Next ret(i, 2) = obj.ControlFormat.value ret(i, 3) = obj.Left ret(i, 4) = obj.Top ret(i, 5) = obj.Width ret(i, 6) = obj.Height ret(i, 7) = obj.TopLeftCell.Address(False, False) ret(i, 8) = obj.TopLeftCell.Row ret(i, 9) = obj.TopLeftCell.Column ret(i, 10) = obj.Left.BottomRightCell.Address(False, False) ret(i, 11) = obj.Left.BottomRightCell.Row ret(i, 12) = obj.Left.BottomRightCell.Column i = i + 1 End If ' 指定なし又は、それ以外のオートシェイプなどの場合 ElseIf objType = -999 Or obj.Type = objType Then ret(i, 0) = obj.Type ret(i, 1) = obj.AlternativeText ' TextFrameプロパティが使用できない(レイアウト枠がない)オブジェクトは除外 On Error Resume Next ret(i, 2) = obj.TextFrame.Characters.Text ret(i, 3) = obj.Left ret(i, 4) = obj.Top ret(i, 5) = obj.Width ret(i, 6) = obj.Height ret(i, 7) = obj.TopLeftCell.Address(False, False) ret(i, 8) = obj.TopLeftCell.Row ret(i, 9) = obj.TopLeftCell.Column ret(i, 10) = obj.Left.BottomRightCell.Address(False, False) ret(i, 11) = obj.Left.BottomRightCell.Row ret(i, 12) = obj.Left.BottomRightCell.Column i = i + 1 End If Next End If getShapesProperty = ret End Function ' ##################################################################################################################### ' # ' # 配列操作系ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' 機能 :引数が配列か判定し、配列の場合は空かどうかも判定する ' 引数 :varArray 配列 ' 戻り値:判定結果(1:配列/0:空の配列/-1:配列じゃない) ' ********************************************************************************************************************* ' Public Function IsArrayEx(varArray As Variant) As Long On Error GoTo ERROR_ If IsArray(varArray) Then IsArrayEx = IIf(UBound(varArray) >= 0, 1, 0) Else IsArrayEx = -1 End If Exit Function ERROR_: If Err.Number = 9 Then IsArrayEx = 0 End If End Function ' ********************************************************************************************************************* ' 機能 :実行結果を保持する二次元配列変数を定義するFunction ' ********************************************************************************************************************* ' Function reDimResult(ByVal topLevelElementSize As Integer, ByRef results() As Variant) Select Case IsArrayEx(results) Case 1 ' resultsが初期化済の場合 ' 現在のレコード数 + 1行領域を確保 ReDim Preserve results(topLevelElementSize, UBound(results, 2) + 1) Case 0 ' resultsが1度も初期化されていない場合 ' 1行領域を確保 ReDim Preserve results(topLevelElementSize, 0) End Select End Function ' ********************************************************************************************************************* ' 機能 :一次元配列に新たな要素を追加する ' ********************************************************************************************************************* ' Function 一次元配列に値を追加(ByRef valueList As Variant, ByVal 追加設定値 As String) ' ファイル名を取得する Select Case IsArrayEx(valueList) Case 1 ReDim Preserve valueList(UBound(valueList) + 1) Case 0 ReDim Preserve valueList(0) End Select ' 追加したリストに、設定値を格納。 valueList(UBound(valueList)) = 追加設定値 End Function ' ********************************************************************************************************************* ' 機能 :二次元配列の行と列を入れ替える ' ********************************************************************************************************************* ' Function 二次元配列行列逆転(ByRef var二次元配列 As Variant) Dim var逆転後配列 As Variant ReDim var逆転後配列( _ LBound(var二次元配列, 2) To UBound(var二次元配列, 2), _ LBound(var二次元配列) To UBound(var二次元配列)) Dim i, j As Long For i = LBound(var二次元配列) To UBound(var二次元配列, 2) For j = LBound(var二次元配列) To UBound(var二次元配列) var逆転後配列(i, j) = var二次元配列(j, i) Next Next 二次元配列行列逆転 = var逆転後配列 End Function ' ##################################################################################################################### ' # ' # 装飾系ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' 機能 :対象セルにハイパーリンク数式を適用する ' ********************************************************************************************************************* ' Public Function editHYPERLINK数式( _ ByVal strフォルダ名 As String, _ ByVal strファイル名 As String, _ ByVal strシート名 As String, _ ByVal str座標 As String) As String editHYPERLINK数式 = _ "=HYPERLINK(""[" & strフォルダ名 & "\" & strファイル名 & "]" & _ strシート名 & "!" & str座標 & """,""" & str座標 & """)" End Function ' ********************************************************************************************************************* ' 機能 :対象セル範囲内で検索文字列に該当した文字列を赤太文字にする ' ********************************************************************************************************************* ' Function 検索該当文字の赤太文字化(prmRange As Range, prmTargetString As String) Dim txt As String Dim i, m As Integer Dim targetRange As Range If prmTargetString = "" Then Exit Function End If For Each targetRange In prmRange txt = targetRange.value m = Len(prmTargetString) i = InStr(1, txt, prmTargetString) Do Until i = 0 With prmRange.Characters(i, m) .Font.Bold = True .Font.ColorIndex = 3 End With i = InStr(i + 1, txt, prmTargetString) Loop Next Set targetRange = Nothing End Function ' ##################################################################################################################### ' # ' # シート情報取得系ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' 機能 :タイトル名指定でリスト値を取得 ' ※リスト値がなかった場合、配列の要素数1(値は空)が返却されます。 ' ********************************************************************************************************************* ' Function タイトル名指定でリスト値を取得(titleName As String, targetSheet As Worksheet) As Variant Dim targetRangeList As Range Dim targetVariantList As Variant Set targetRangeList = タイトル名指定でリスト値のRange情報を取得(titleName, targetSheet) ' 配列か判定 If targetRangeList.count = 1 Then targetVariantList = Array(targetRangeList.Item(1).value) Else targetVariantList = targetRangeList.value End If タイトル名指定でリスト値を取得 = targetVariantList End Function ' ********************************************************************************************************************* ' 機能 :タイトル名指定でリスト値のRange情報を取得 ' ※リスト値がなかった場合、リスト値エリアの1行目(値は空)のRange情報が返却されます。 ' ********************************************************************************************************************* ' Function タイトル名指定でリスト値のRange情報を取得(titleName As String, targetSheet As Worksheet) As Range ' 検索ヒット数 Dim matchCount As Long Dim checkValue As String ' シート内にタイトル名が複数設定されていない事を確認する。 matchCount = WorksheetFunction.CountIf(targetSheet.UsedRange, titleName) If 1 <> matchCount Then MsgBox "タイトル「" & titleName & "」が複数見つかったため、処理を中断しました。" End End If ' タイトル名のRange情報を取得 Dim FoundCell As Range Set FoundCell = targetSheet.UsedRange.Find(what:=titleName, LookIn:=xlValues, _ LookAt:=xlPart, MatchCase:=False, MatchByte:=False) Dim i, MaxRow, MaxCol As Long ' タイトルに対するリスト値を取得(空白行込み) With targetSheet With .Range(.Cells(FoundCell.Row, FoundCell.Column), .Cells(Rows.count, FoundCell.Column)) MaxRow = .Find("*", , xlFormulas, , xlByRows, xlPrevious).Row MaxCol = .Find("*", , xlFormulas, , xlByColumns, xlPrevious).Column End With ' MaxRowを、空白行より一行↑のリスト値の行数に設定する。 For i = 1 To (MaxRow - FoundCell.Row) checkValue = .Cells(FoundCell.Row + i, MaxCol).value If "" = checkValue Or InStr(1, checkValue, TITLE_NAME_PREFIX) > 0 Then If 1 = i Then Call 処理続行判断("タイトル名「" + titleName + "」に対するリスト値が設定されていません。") MaxRow = FoundCell.Row + 1 Else MaxRow = FoundCell.Row + i - 1 End If Exit For End If Next ' リスト値を返却 Set タイトル名指定でリスト値のRange情報を取得 = _ targetSheet.Range(.Cells((FoundCell.Row + 1), FoundCell.Column), .Cells(MaxRow, MaxCol)) End With End Function ' ********************************************************************************************************************* ' 機能 :引数で指定された行が選択状態であるか判定する ' ********************************************************************************************************************* ' Function is選択状態(ByVal lng対象行 As Long) Dim rng As Range For Each rng In Selection.Rows If rng.Row = lng対象行 Then is選択状態 = True Exit Function End If Next rng is選択状態 = False End Function
マクロ下書(タスク算出)
Option Explicit ' タスクシート設定 Const lng開始行 As Long = 3 Dim var全体開始日 As Variant ' 全体の開始日 Const txt全体開始日アドレス As String = "B1" ' シート名 Const cnst休日シート名 As String = "休日" Const cnst担当者シート名 As String = "担当者" Const idx処理中日付 As Long = 1 Const idx工数 As Long = 2 Const idx1日あたり工数 As Long = 3 Const idx休日リスト As Long = 4 Dim txt休日リスト() As String Dim lngID列, lng先行タスクID列, lng同一タスクID列, lng優先度列, lngタスク列, lng工数列, lng担当者列 As Long Dim lng指定開始日列, lng指定終了日列, lng予定開始日列, lng予定終了日列 As Long Dim lng最終行 As Long Dim lng最終列 As Long Dim rngタスク一覧 As Range Dim obj担当者 As Object ' --------------------------------------------------------------------------------------------------------------------- ' スケジュール算出 ' --------------------------------------------------------------------------------------------------------------------- Sub スケジュール算出() var全体開始日 = Range(txt全体開始日アドレス) lng最終行 = 最終行取得(ActiveSheet) lng最終列 = 最終列取得(ActiveSheet) With ActiveSheet Set rngタスク一覧 = .Range(.Cells(lng開始行, 1), .Cells(lng最終行, lng最終列)) End With Call 優先度順に並び替え ' ----------------------------------------------------------------------------------------------------------------- ' 休日シートの読み込み ' ----------------------------------------------------------------------------------------------------------------- ' Dim obj休日シート As Worksheet: Set obj休日シート = ActiveWorkbook.Sheets(cnst休日シート名) Dim var休日リスト As Variant With obj休日シート var休日リスト = .Range(.Cells(2, 1), .Cells(最終行取得(obj休日シート), 1)) ReDim txt休日リスト(LBound(var休日リスト, 1) To UBound(var休日リスト, 1)) Dim i As Long For i = LBound(var休日リスト) To UBound(var休日リスト) txt休日リスト(i) = var休日リスト(i, 1) Next End With ' ----------------------------------------------------------------------------------------------------------------- ' 担当者シートの読み込み ' ----------------------------------------------------------------------------------------------------------------- ' Dim obj担当者シート As Worksheet: Set obj担当者シート = ActiveWorkbook.Sheets(cnst担当者シート名) Dim var担当者リスト As Variant With obj担当者シート var担当者リスト = .Range(.Cells(2, 1), _ .Cells(最終行取得(obj担当者シート), 最終列取得(obj担当者シート))) Set obj担当者 = CreateObject("Scripting.Dictionary") Dim j As Long For j = LBound(var担当者リスト) To UBound(var担当者リスト) Dim var担当者休日リスト As Variant: var担当者休日リスト = txt休日リスト If var担当者リスト(j, 3) <> "" Then Dim k As Long Dim tmp担当者休日リスト As Variant: tmp担当者休日リスト = Split(var担当者リスト(j, 3), ",") ReDim Preserve var担当者休日リスト(UBound(txt休日リスト) + UBound(tmp担当者休日リスト)) For k = LBound(tmp担当者休日リスト) To UBound(tmp担当者休日リスト) var担当者休日リスト(UBound(txt休日リスト) + k) = tmp担当者休日リスト(k) Next End If Dim var担当者詳細リスト(1 To 4) As Variant var担当者詳細リスト(idx処理中日付) = var全体開始日 var担当者詳細リスト(idx工数) = 0 ' 処理中の工数(初期値0を設定) var担当者詳細リスト(idx1日あたり工数) = var担当者リスト(j, 2) ' 1日あたりの工数 var担当者詳細リスト(idx休日リスト) = var担当者休日リスト ' 休日 obj担当者.Add var担当者リスト(j, 1), var担当者詳細リスト Next End With ' ----------------------------------------------------------------------------------------------------------------- ' 予定開始終了日設定 ' ----------------------------------------------------------------------------------------------------------------- ' Call 予定開始終了日設定 End Sub ' --------------------------------------------------------------------------------------------------------------------- ' 優先度準に並び替え ' --------------------------------------------------------------------------------------------------------------------- Function 優先度順に並び替え() rngタスク一覧.Select ActiveWorkbook.Worksheets("タスク").Sort.SortFields.Clear ActiveWorkbook.Worksheets("タスク").Sort.SortFields.Add Key:=Range("D4:D20"), _ SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal ActiveWorkbook.Worksheets("タスク").Sort.SortFields.Add Key:=Range("G4:G20"), _ SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal ActiveWorkbook.Worksheets("タスク").Sort.SortFields.Add Key:=Range("H4:H20"), _ SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal ActiveWorkbook.Worksheets("タスク").Sort.SortFields.Add Key:=Range("I4:I20"), _ SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal With ActiveWorkbook.Worksheets("タスク").Sort .SetRange rngタスク一覧 .Header = xlYes .MatchCase = False .Orientation = xlTopToBottom .SortMethod = xlPinYin .Apply End With End Function ' --------------------------------------------------------------------------------------------------------------------- ' タスクの一覧をvariantで取得 ' --------------------------------------------------------------------------------------------------------------------- Function タスク一覧取得() As Variant Dim varタスク一覧 As Variant With ActiveSheet varタスク一覧 = .Range(.Cells(lng開始行, 1), .Cells(lng最終行, lng最終列)) End With Dim i As Long For i = LBound(varタスク一覧, 2) To UBound(varタスク一覧, 2) Dim txtセルの値 As String: txtセルの値 = varタスク一覧(1, i) Select Case txtセルの値 Case "ID" lngID列 = i Case "先行タスクID" lng先行タスクID列 = i Case "同一タスクID" lng同一タスクID列 = i Case "優先度" lng優先度列 = i Case "タスク" lngタスク列 = i Case "工数" lng工数列 = i Case "担当者" lng担当者列 = i Case "指定開始日" lng指定開始日列 = i Case "指定終了日" lng指定終了日列 = i Case "予定開始日" lng予定開始日列 = i Case "予定終了日" lng予定終了日列 = i End Select Next タスク一覧取得 = varタスク一覧 End Function ' --------------------------------------------------------------------------------------------------------------------- ' 予定開始終了日を設定する ' --------------------------------------------------------------------------------------------------------------------- Sub 予定開始終了日設定() ' Dim var日付記録(1 To 2) As Variant ' var日付記録(1) = var全体開始日 ' var日付記録(2) = 0 Dim varタスク一覧 As Variant: varタスク一覧 = タスク一覧取得 Dim i As Long For i = LBound(varタスク一覧) + 1 To UBound(varタスク一覧) ' 処理中のタスク情報の取得 Dim lng工数 As Long: lng工数 = varタスク一覧(i, lng工数列) Dim txt担当者 As String: txt担当者 = varタスク一覧(i, lng担当者列) If obj担当者.Exists(txt担当者) Then Dim var担当者情報 As Variant: var担当者情報 = obj担当者.Item(txt担当者) Dim lng1日あたりの工数 As Long: lng1日あたりの工数 = var担当者情報(idx1日あたり工数) ' 開始日記録 ActiveSheet.Cells(i + lng開始行 - 1, lng予定開始日列) = var担当者情報(idx処理中日付) Do While (lng工数 > 0) Debug.Print (var担当者情報(idx処理中日付) & " " & var担当者情報(idx工数) & " " & lng工数) ' 対象日の残工数と If (lng工数 + var担当者情報(idx工数)) >= lng1日あたりの工数 Then ' 稼働日ぴったりの場合のみ終了日をプロットする(終了日算出の中でプロットできないため) If (lng工数 + var担当者情報(idx工数)) = lng1日あたりの工数 Then ActiveSheet.Cells(i + lng開始行 - 1, lng予定終了日列) = var担当者情報(idx処理中日付) End If lng工数 = lng工数 - (lng1日あたりの工数 - var担当者情報(idx工数)) var担当者情報(idx処理中日付) = 日付を進める(var担当者情報(idx処理中日付), var担当者情報(idx休日リスト)) var担当者情報(idx工数) = 0 Else var担当者情報(idx工数) = var担当者情報(idx工数) + lng工数 lng工数 = 0 ' 終了日記録 ActiveSheet.Cells(i + lng開始行 - 1, lng予定終了日列) = var担当者情報(idx処理中日付) End If Loop obj担当者.Item(txt担当者) = var担当者情報 End If Next Dim obj開始表 As Object Set obj開始表 = CreateObject("Scripting.Dictionary") End Sub ' --------------------------------------------------------------------------------------------------------------------- ' 予定開始終了日を設定する ' --------------------------------------------------------------------------------------------------------------------- Function 日付を進める(ByVal prm日付 As Variant, ByVal prm休日リスト As Variant) Dim var進めた後の日付 As Variant: var進めた後の日付 = prm日付 + 1 Do While True ' 月曜日から金曜日の場合 If Weekday(var進めた後の日付) <= 1 Or 7 <= Weekday(var進めた後の日付) Then var進めた後の日付 = var進めた後の日付 + 1 ElseIf 配列に存在するかチェック(var進めた後の日付, prm休日リスト) Then var進めた後の日付 = var進めた後の日付 + 1 Else 日付を進める = var進めた後の日付 Exit Function End If Loop End Function Function 配列に存在するかチェック(ByVal prm対象文字列 As Variant, ByVal prm日付配列 As Variant) As Boolean Dim i As Long For i = LBound(prm日付配列) To UBound(prm日付配列) If CDate(prm対象文字列) = CDate(prm日付配列(i)) Then 配列に存在するかチェック = True Exit Function End If Next 配列に存在するかチェック = False End Function
Option Explicit ' --------------------------------------------------------------------------------------------------------------------- ' 定数 ' --------------------------------------------------------------------------------------------------------------------- Public Const TITLE_NAME_PREFIX = "▼" ' --------------------------------------------------------------------------------------------------------------------- ' 変数 ' --------------------------------------------------------------------------------------------------------------------- Dim var開始時刻 As Variant ' ##################################################################################################################### ' # ' # ログ系ユーティリティ ' # ' ##################################################################################################################### Sub log(ByVal strメッセージ As String) Debug.Print Format(Now(), "HH:mm:ss ") & strメッセージ End Sub ' ##################################################################################################################### ' # ' # ステータスバー操作系ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' * 機能 :ステータスバーに表示する処理時間を初期化する ' ********************************************************************************************************************* ' Sub init開始時刻() var開始時刻 = Now() End Sub ' ********************************************************************************************************************* ' * 機能 :処理時間の開始時刻を取得する ' ********************************************************************************************************************* ' Function get開始時刻() get開始時刻 = var開始時刻 End Function ' ********************************************************************************************************************* ' * 機能 :処理時間を HH:mm:ss 形式で取得する ' ********************************************************************************************************************* ' Function get処理時刻() get処理時刻 = Format(Now() - var開始時刻, "HH:mm:ss") End Function ' ********************************************************************************************************************* ' * 機能 :ステータスバーに経過時間付でメッセージを表示する ' ********************************************************************************************************************* ' Sub setステータスバー(ByVal strメッセージ As String) If IsEmpty(var開始時刻) Then var開始時刻 = Now() End If Application.StatusBar = get処理時刻() & " " & strメッセージ End Sub ' ##################################################################################################################### ' # ' # ブック、シート操作系ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' * 機能 :引数で渡されたシート名以外のシートを削除する ' ********************************************************************************************************************* ' ' Function 不要シート削除(対象ブック情報 As Workbook, ByVal 残すシート名 As String) Dim 前状態 As Boolean 前状態 = Application.DisplayAlerts Application.DisplayAlerts = False Dim ws As Worksheet For Each ws In 対象ブック情報.Worksheets If ws.Name <> 残すシート名 Then Worksheets(ws.Name).Delete End If Next ws Application.DisplayAlerts = 前状態 End Function ' ##################################################################################################################### ' # ' # ダイアログ操作系ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' * 機能 :処理続行 or 中止確認ダイアログを表示する ' ********************************************************************************************************************* ' Function 処理続行判断(message As String) Dim rc As VbMsgBoxResult rc = MsgBox(message + Chr(10) + "処理を続行しますか?", vbYesNo, vbQuestion) If rc = vbYes Then MsgBox "処理を続けます", vbInformation Else MsgBox "処理を中止しました。", vbCritical ' マクロの実行中止 End End If End Function ' ##################################################################################################################### ' # ' # オートシェイプ操作系ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' 機能名:対象シート上にあるオブジェクトおnプロパティを取得する ' 戻り :getShapesProperty as String(2, n) ' (0, n) type ' (1, n) name ' (2, n) TextFrame.Characters.text ' (3, n) Left ' (4, n) Top ' (5, n) Width ' (6, n) Height ' (7, n) TopLeftCell.Address(False, False) ' (8, n) TopLeftCell.row ' (9, n) TopLeftCell.Column ' (10, n) BottomRightCell.Address(False, False) ' (11, n) BottomRightCell.row ' (12, n) BottomRightCell.Column ' ' ********************************************************************************************************************* ' Function getShapesProperty(ByRef targetSheet As Worksheet, Optional ByVal objType As Long = -999, Optional ByVal formCtlType As Long = -999) As Variant Dim ret As Variant Dim i As Long Dim obj As Variant ' 配列の作成。 i = 0 For Each obj In targetSheet.Shapes ' FORMコントロールの場合 If obj.Type = objType Then ' 渡されたフォームコントロールタイプが一致した場合、カウントアップ If obj.FormControlType = formCtlType Then i = i + 1 End If ' 指定なし又は、それ以外のオートシェイプ ElseIf objType = -999 Or obj.Type = objType Then i = i + 1 End If Next ' 対象のオートシェイプがみつかった場合のみ、そのオブジェクトの格納を行う。 If 0 <> i Then ReDim ret(i - 1, 12) ' 配列の作成 i = 0 ' オブジェクト情報の設定 For Each obj In targetSheet.Shapes ' formコントロールの場合 If obj.Type = objType Then ' 渡されたフォームコrントロールタイプが一致した場合、値を取得する。 If obj.FormControlType = formCtlType Then ret(i, 0) = obj.Type ret(i, 1) = obj.AlternativeText ' TextFrameプロパティが使用できない(レイアウト枠がない)オブジェクトは除外 On Error Resume Next ret(i, 2) = obj.ControlFormat.Value ret(i, 3) = obj.Left ret(i, 4) = obj.Top ret(i, 5) = obj.Width ret(i, 6) = obj.Height ret(i, 7) = obj.TopLeftCell.Address(False, False) ret(i, 8) = obj.TopLeftCell.Row ret(i, 9) = obj.TopLeftCell.Column ret(i, 10) = obj.Left.BottomRightCell.Address(False, False) ret(i, 11) = obj.Left.BottomRightCell.Row ret(i, 12) = obj.Left.BottomRightCell.Column i = i + 1 End If ' 指定なし又は、それ以外のオートシェイプなどの場合 ElseIf objType = -999 Or obj.Type = objType Then ret(i, 0) = obj.Type ret(i, 1) = obj.AlternativeText ' TextFrameプロパティが使用できない(レイアウト枠がない)オブジェクトは除外 On Error Resume Next ret(i, 2) = obj.TextFrame.Characters.Text ret(i, 3) = obj.Left ret(i, 4) = obj.Top ret(i, 5) = obj.Width ret(i, 6) = obj.Height ret(i, 7) = obj.TopLeftCell.Address(False, False) ret(i, 8) = obj.TopLeftCell.Row ret(i, 9) = obj.TopLeftCell.Column ret(i, 10) = obj.Left.BottomRightCell.Address(False, False) ret(i, 11) = obj.Left.BottomRightCell.Row ret(i, 12) = obj.Left.BottomRightCell.Column i = i + 1 End If Next End If getShapesProperty = ret End Function ' ##################################################################################################################### ' # ' # 配列操作系ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' 機能 :引数が配列か判定し、配列の場合は空かどうかも判定する ' 引数 :varArray 配列 ' 戻り値:判定結果(1:配列/0:空の配列/-1:配列じゃない) ' ********************************************************************************************************************* ' Public Function IsArrayEx(varArray As Variant) As Long On Error GoTo ERROR_ If IsArray(varArray) Then IsArrayEx = IIf(UBound(varArray) >= 0, 1, 0) Else IsArrayEx = -1 End If Exit Function ERROR_: If Err.Number = 9 Then IsArrayEx = 0 End If End Function ' ********************************************************************************************************************* ' 機能 :実行結果を保持する二次元配列変数を定義するFunction ' ********************************************************************************************************************* ' Function reDimResult(ByVal topLevelElementSize As Integer, ByRef results() As Variant) Select Case IsArrayEx(results) Case 1 ' resultsが初期化済の場合 ' 現在のレコード数 + 1行領域を確保 ReDim Preserve results(topLevelElementSize, UBound(results, 2) + 1) Case 0 ' resultsが1度も初期化されていない場合 ' 1行領域を確保 ReDim Preserve results(topLevelElementSize, 0) End Select End Function ' ********************************************************************************************************************* ' 機能 :一次元配列に新たな要素を追加する ' ********************************************************************************************************************* ' Function 一次配列に値を追加(ByRef valueList As Variant, ByVal 追加設定値 As String) ' ファイル名を取得する Select Case IsArrayEx(valueList) Case 1 ReDim Preserve valueList(UBound(valueList) + 1) Case 0 ReDim Preserve valueList(0) End Select ' 追加したリストに、設定値を格納。 valueList(UBound(valueList)) = 追加設定値 End Function ' ********************************************************************************************************************* ' 機能 :二次元配列の行と列を入れ替える ' ********************************************************************************************************************* ' Function 二次元配列行列逆転(ByRef var二次元配列 As Variant) Dim var逆転後配列 As Variant ReDim var逆転後配列( _ LBound(var二次元配列, 2) To UBound(var二次元配列, 2), _ LBound(var二次元配列) To UBound(var二次元配列)) Dim i, j As Long For i = LBound(var二次元配列) To UBound(var二次元配列, 2) For j = LBound(var二次元配列) To UBound(var二次元配列) var逆転後配列(i, j) = var二次元配列(j, i) Next Next 二次元配列行列逆転 = var逆転後配列 End Function ' ##################################################################################################################### ' # ' # 装飾系ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' 機能 :対象セルにハイパーリンク数式を適用する ' ********************************************************************************************************************* ' Public Function editHYPERLINK数式( _ ByVal strフォルダ名 As String, _ ByVal strファイル名 As String, _ ByVal strシート名 As String, _ ByVal str座標 As String) As String editHYPERLINK数式 = _ "=HYPERLINK(""[" & strフォルダ名 & "\" & strファイル名 & "]" & _ strシート名 & "!" & str座標 & """,""" & str座標 & """)" End Function ' ********************************************************************************************************************* ' 機能 :対象セル範囲内で検索文字列に該当した文字列を赤太文字にする ' ********************************************************************************************************************* ' Function 検索該当文字の赤太文字化(prmRange As Range, prmTargetString As String) Dim txt As String Dim i, m As Integer Dim targetRange As Range If prmTargetString = "" Then Exit Function End If For Each targetRange In prmRange txt = targetRange.Value m = Len(prmTargetString) i = InStr(1, txt, prmTargetString) Do Until i = 0 With prmRange.Characters(i, m) .Font.Bold = True .Font.ColorIndex = 3 End With i = InStr(i + 1, txt, prmTargetString) Loop Next Set targetRange = Nothing End Function ' ##################################################################################################################### ' # ' # シート情報取得系ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' 機能 :タイトル名指定でリスト値を取得 ' ※リスト値がなかった場合、配列の要素数1(値は空)が返却されます。 ' ********************************************************************************************************************* ' Function タイトル名指定でリスト値を取得(titleName As String, targetSheet As Worksheet) As Variant Dim targetRangeList As Range Dim targetVariantList As Variant Set targetRangeList = タイトル名指定でリスト値のRange情報を取得(titleName, targetSheet) ' 配列か判定 If targetRangeList.Count = 1 Then targetVariantList = Array(targetRangeList.Item(1).Value) Else targetVariantList = targetRangeList.Value End If タイトル名指定でリスト値を取得 = targetVariantList End Function ' ********************************************************************************************************************* ' 機能 :タイトル名指定でリスト値のRange情報を取得 ' ※リスト値がなかった場合、リスト値エリアの1行目(値は空)のRange情報が返却されます。 ' ********************************************************************************************************************* ' Function タイトル名指定でリスト値のRange情報を取得(titleName As String, targetSheet As Worksheet) As Range ' 検索ヒット数 Dim matchCount As Long Dim checkValue As String ' シート内にタイトル名が複数設定されていない事を確認する。 matchCount = WorksheetFunction.CountIf(targetSheet.UsedRange, titleName) If 1 <> matchCount Then MsgBox "タイトル「" & titleName & "」が複数見つかったため、処理を中断しました。" End End If ' タイトル名のRange情報を取得 Dim FoundCell As Range Set FoundCell = targetSheet.UsedRange.Find(what:=titleName, LookIn:=xlValues, _ LookAt:=xlPart, MatchCase:=False, MatchByte:=False) Dim i, MaxRow, MaxCol As Long ' タイトルに対するリスト値を取得(空白行込み) With targetSheet With .Range(.Cells(FoundCell.Row, FoundCell.Column), .Cells(Rows.Count, FoundCell.Column)) MaxRow = .Find("*", , xlFormulas, , xlByRows, xlPrevious).Row MaxCol = .Find("*", , xlFormulas, , xlByColumns, xlPrevious).Column End With ' MaxRowを、空白行より一行↑のリスト値の行数に設定する。 For i = 1 To (MaxRow - FoundCell.Row) checkValue = .Cells(FoundCell.Row + i, MaxCol).Value If "" = checkValue Or InStr(1, checkValue, TITLE_NAME_PREFIX) > 0 Then If 1 = i Then Call 処理続行判断("タイトル名「" + titleName + "」に対するリスト値が設定されていません。") MaxRow = FoundCell.Row + 1 Else MaxRow = FoundCell.Row + i - 1 End If Exit For End If Next ' リスト値を返却 Set タイトル名指定でリスト値のRange情報を取得 = _ targetSheet.Range(.Cells((FoundCell.Row + 1), FoundCell.Column), .Cells(MaxRow, MaxCol)) End With End Function Function 最終行取得(ws対象シート As Worksheet) As Long 最終行取得 = ws対象シート.UsedRange.Find("*", , xlFormulas, , xlByRows, xlPrevious).Row End Function Function 最終列取得(ws対象シート As Worksheet) As Long 最終列取得 = ws対象シート.UsedRange.Find("*", , xlFormulas, , xlByColumns, xlPrevious).Column End Function
マクロ
Excelで文字列検索するマクロ
Option Explicit ' --------------------------------------------------------------------------------------------------------------------- ' 定数 ' --------------------------------------------------------------------------------------------------------------------- ' なし ' ********************************************************************************************************************* ' * 機能 :マクロ呼び出し時(シートからの指定用) ' ********************************************************************************************************************* Sub doStart() Call init開始時刻 Dim wsMainSheet As Worksheet Dim fileCheck As Long ' タイトル名に対するリストの情報(Range情報) Dim currentDirPathRangeList As Range, currentDirPathRange As Range Dim subDirCheckBoxRangeList As Range, subDirCheckBoxRange As Range ' 処理対象のファイル名一覧(フルパス&ファイル名) Dim fileNames() As String ' ----------------------------------------------------------------------------------------------------------------- ' 初期化処理 ' ----------------------------------------------------------------------------------------------------------------- ' 処理対象の拡張子を設定する。 Dim fileExtention As Variant fileExtention = Split(FILE_EXTENSION, ",") ' 固有処理(マクロ呼び出し元)側のシート情報を取得する。 ' Set wsMainSheet = MainSheet Set wsMainSheet = ActiveSheet ' 固有処理(マクロ呼び出し元)側のパス情報を取得する。 Set currentDirPathRangeList = タイトル名指定でリスト値のRange情報を取得(TITLE_NAME_BY_TARGET_DIR, wsMainSheet) Set subDirCheckBoxRangeList = タイトル名指定でリスト値のRange情報を取得(TITLE_NAME_BY_DO_SUB_DIR, wsMainSheet) ' ★ConcreateProcess側の処理の呼び出し(呼び出し先のProcedure側ではツールごとの固有の実装を行う) Call 前処理(wsMainSheet) ' ----------------------------------------------------------------------------------------------------------------- ' パスの存在チェック ' ----------------------------------------------------------------------------------------------------------------- With wsMainSheet Dim i As Long i = 0 ' 対象ディレクトリ分ループ If Not (currentDirPathRangeList Is Nothing) Then For Each currentDirPathRange In currentDirPathRangeList ' ディレクトリまたは、ファイルの存在チェック fileCheck = isDirectoryExist(CStr(currentDirPathRange.Value)) If 0 > fileCheck Then MsgBox "以下のパスは存在しません。" + Chr(10) + "「" + currentDirPathRange.Value + "」" End End If i = i + 1 Next End If End With ' ----------------------------------------------------------------------------------------------------------------- ' ファイル名の収集 ' ----------------------------------------------------------------------------------------------------------------- Call setステータスバー("対象ファイル集計中...") With ActiveSheet i = 1 '対象ディレクトリ分ループ If Not (currentDirPathRangeList Is Nothing) Then For Each currentDirPathRange In currentDirPathRangeList '指定の値がファイルの場合、その値をリストに追加し、ディレクトリの場合は、ファイル名の一覧を動的に取得して追加する。 fileCheck = isDirectoryExist(CStr(currentDirPathRange.Value)) If 2 = fileCheck Then ' 指定の値がファイルだった場合、その値をリストに追加 ' フルパス&ファイル名を追加格納。 Call 一次配列に値を追加(fileNames, CStr(currentDirPathRange.Value)) Else ' <オートシェイプ情報の取得> Dim shapesCount As Long Dim checkBoxChecked As Variant Dim topLeftCellRow As Variant, topLeftCellColumn As Variant ' オートシェイプ(チェックボックス)情報を取得。 Dim ShapesInfoList As Variant ShapesInfoList = getShapesProperty(wsMainSheet, msoFormControl, xlCheckBox) ' 対象セル行のチェックボックスのチェック状態を取得(boolean形式で) checkBoxChecked = False If IsArrayEx(ShapesInfoList) > 0 Then For shapesCount = LBound(ShapesInfoList) To UBound(ShapesInfoList) topLeftCellRow = ShapesInfoList(shapesCount, 8) topLeftCellColumn = ShapesInfoList(shapesCount, 9) ' 取得したチェックボックスが以下の条件に一致した場合、対象と判断する。 ' ・チェックボックスの行が、処理中の対象ディレクトリの行と一致。 ' ・チェックボックスの列が、タイトルの列と一致。 If Not IsEmpty(topLeftCellRow) And topLeftCellRow = currentDirPathRange.Row _ And topLeftCellColumn = subDirCheckBoxRangeList.Item(0).Column Then ' チェックボックス値を取得する。 If 1 = ShapesInfoList(shapesCount, 2) Then checkBoxChecked = True End If Exit For End If Next shapesCount End If ' 現在のディレクトリ配下のファイル名を取得 Call doRepeat(currentDirPathRange, fileExtention, fileNames, checkBoxChecked) End If i = i + 1 Next End If End With ' ----------------------------------------------------------------------------------------------------------------- ' ファイル処理メソッドの呼び出し ' ----------------------------------------------------------------------------------------------------------------- Call doTargetFiles(fileNames) ' ★ConcreateProcess側の処理の呼び出し(呼び出し先のProcedure側ではツールごとの固有の実装を行う) Call 後処理(wsMainSheet) MsgBox "処理が終了しました。(処理時間:" & get処理時刻() & ")" End Sub ' ********************************************************************************************************************* ' * 機能 :対象ファイルの処理を行う。 ' * 引数 :varArray 配列 ' * 戻り値:判定結果(1:配列/0:空の配列/-1:配列ではない) ' ********************************************************************************************************************* ' Function doTargetFiles(fileNames() As String) ' ファイル名の一覧が空だった場合、当Functionを中断する。 If 1 > IsArrayEx(fileNames) Then MsgBox "処理対象ファイルが存在しません。" Exit Function End If Dim FSO Set FSO = CreateObject("Scripting.FileSystemObject") Dim fileName As Variant Dim targetWB As Workbook Dim targetSheet As Worksheet Dim index As Long, total As Long Dim defaultSaveFormat As Long defaultSaveFormat = Application.defaultSaveFormat ' シート毎の処理呼び出し不要フラグ Dim unDealTargetSheetFlag As Boolean ' 処理結果保持用 Dim results() As Variant index = 1 total = UBound(fileNames) + 1 Application.DisplayAlerts = False ' ファイルを開く際の警告を無効 Application.ScreenUpdating = False ' 画面表示更新を無効 For Each fileName In fileNames ' ------------------------------------------------------------------------------------------------------------- ' 対象ブックを開いて、全シート分の処理を行う。 ' ------------------------------------------------------------------------------------------------------------- Call setステータスバー("(" & index & "/" & total & ")" & FSO.GetFileName(fileName)) index = index + 1 Set targetWB = Workbooks.Open(fileName, UpdateLinks:=0, IgnoreReadOnlyRecommended:=False) ' ★ConcreateProcess側の処理の呼び出し(呼び出し先のProcedure側ではツールごとの固有の実装を行う) unDealTargetSheetFlag = dealTargetWorkbook(fileName, targetWB, results) If False = unDealTargetSheetFlag Then Dim i As Integer For i = 1 To targetWB.Worksheets.Count ' シートの数分ループする Set targetSheet = targetWB.Worksheets(i) ' ★ConcreateProcess側の処理の呼び出し(呼び出し先のProcedure側ではツールごとの固有の実装を行う) Call dealTargetSheet(fileName, targetSheet, results) Next i End If Dim ファイルCLOSE方法区分値 As Long ' ★ConcreateProces側の処理の呼び出し(呼び出し先のProcedure側ではツールごとの固有の実装を行う) ファイルCLOSE方法区分値 = ブック毎後処理(fileName, targetWB, results) If ファイルCLOSE方法区分値 = ファイルCLOSE方法区分.保存しないで閉じる Then targetWB.Close ElseIf ファイルCLOSE方法区分値 = ファイルCLOSE方法区分.保存して閉じる Then targetWB.Save targetWB.Close ElseIf ファイルCLOSE方法区分値 = ファイルCLOSE方法区分.保存しないで閉じない Then ElseIf ファイルCLOSE方法区分値 = ファイルCLOSE方法区分.保存して閉じない Then targetWB.Save ElseIf ファイルCLOSE方法区分値 = ファイルCLOSE方法区分.処理中断 Then End End If Next ' ★ConcreateProcess側の処理の呼び出し(呼び出し先のProcedure側ではツールごとの固有の実装を行う) ' 実行結果の編集(結果のマージ、並び替え、フィルタリング当) Call editResults(results) If Not Not results Then If UBound(results, 2) <> 0 Then ' ファイルの保存形式をexcel2007形式(.xlsx)に変更 Application.defaultSaveFormat = xlOpenXMLWorkbook Set targetWB = Workbooks.Add ' 当ブックにシート「雛形」が用意されている場合、指定ブックの先頭にコピーした後、 ' シート名を「処理結果」に変更する。(ない場合は新規作成ブックのsheet1を利用) Call 雛形シートコピー(targetWB) ' 結果貼り付け行の取得。 ' A列に値が設定されている行を、表題欄としてその行数を取得する Dim MaxRow As Integer With targetWB.ActiveSheet.UsedRange MaxRow = .Find("*", , xlFormulas, , xlByRows, xlPrevious).Row End With ' 結果貼り付け行の設定。 MaxRow = MaxRow + 1 ' 結果貼り付け targetWB.ActiveSheet.Range(Cells(MaxRow, 1), Cells(UBound(results, 2) + 2, UBound(results) + 1)) = 二次元配列行列逆転(results) Dim MaxCol As Integer ' 書式コピー With targetWB.ActiveSheet MaxRow = .UsedRange.Find("*", , xlFormulas, xlByRows, xlPrevious).Row MaxCol = .UsedRange.Find("*", , xlFormulas, xlByColumns, xlPrevious).Column .Range(.Cells(2, 1), .Cells(2, MaxCol)).Copy .Range(.Cells(2 + 1, 1), .Cells(MaxRow, MaxCol)).PasteSpecial (xlPasteFormats) End With ' ★ConcreateProcess側の処理の呼び出し(呼び出し先のProcedure側ではツールごとの固有の実装を行う) Call setStyle(targetWB.ActiveSheet) ' "A1"を選択状態にする targetWB.ActiveSheet.Cells(1, 1).Select ' シート名「処理結果」以外のシートを削除する Call 不要シート削除(targetWB, RESULT_SHEET_NAME) Else MsgBox "処理結果は0件です。" End If Else MsgBox "処理結果は0件です。" End If Application.DisplayAlerts = True Application.ScreenUpdating = True Application.StatusBar = False ' ファイルの保存形式を元の状態に戻す Application.defaultSaveFormat = defaultSaveFormat If Not Not results Then If UBound(results, 2) <> 0 Then targetWB.Activate End If End If End Function ' ********************************************************************************************************************* ' * 機能 :当ブックのシート「雛形」を指定ブックの先頭にコピーした後、 ' * シート名を「処理結果」に変更する ' ********************************************************************************************************************* ' Sub 雛形シートコピー(targetWB As Workbook) Dim myWorkBook As String Dim newWorkBook As String Dim targetSheet As Worksheet Dim sheetName As String ' マクロを実行中のブック名を取得 myWorkBook = ThisWorkbook.Name ' 新規ブック名を取得 newWorkBook = targetWB.Name ' マクロ実行時のブックをアクティブにする Workbooks(myWorkBook).Activate ' シート「雛形」があった場合、指定ブックにコピー(一番前に挿入)する Dim i As Integer For i = 1 To Workbooks(myWorkBook).Worksheets.Count ' シートの数分ループする Set targetSheet = Workbooks(myWorkBook).Worksheets(i) If TEMPLATE_SHEET_NAME = targetSheet.Name Then Workbooks(myWorkBook).Sheets(TEMPLATE_SHEET_NAME).Copy _ Before:=Workbooks(newWorkBook).Sheets(1) End If Next i ' マクロを実行中のブックをアクティブにする Workbooks(targetWB.Name).Sheets(TEMPLATE_SHEET_NAME).Activate ' シート名を「処理結果」に変更する Workbooks(targetWB.Name).Sheets(TEMPLATE_SHEET_NAME).Name = RESULT_SHEET_NAME End Sub
Option Explicit ' --------------------------------------------------------------------------------------------------------------------- ' 定数(共通) ' --------------------------------------------------------------------------------------------------------------------- ' タイトル名(共通) Public Const TITLE_NAME_BY_TARGET_DIR = "▼ファイル" Public Const TITLE_NAME_BY_DO_SUB_DIR = "▼配下のディレクトリも対象" ' 雛形シートコピー用(共通) Public Const TEMPLATE_SHEET_NAME = "雛形" Public Const RESULT_SHEET_NAME = "処理結果" ' 対象の拡張子 Public Const FILE_EXTENSION = "xls,xlsx,xlsm" ' --------------------------------------------------------------------------------------------------------------------- ' 定数(対象シート固有) ' --------------------------------------------------------------------------------------------------------------------- ' タイトル文字列(対象シート固有) Private Const TITLE_NAME_BY_SEARCH_WORD = "▼検索ワード" ' 処理結果シートデータ貼付け部の列数 Private Const RESULT_COL_LENGTH = 6 ' --------------------------------------------------------------------------------------------------------------------- ' 定数 ' --------------------------------------------------------------------------------------------------------------------- ' 検索文言リスト Private searchArgList As Variant ' 処理した件数 Dim resultCount As Long ' ##################################################################################################################### ' # ' # テンプレートメソッド(AbstractProcessから呼び出されるメソッド) ' # ' # 1. 前処理() 処理実行前に1度だけ実行したい処理を実装する ' # 2. dealTargetWorkbook() 検出されたファイルのブックごとに行いたい処理を実装する(シート毎の処理呼び出しが不要かの判定値(boolean)を返却する) ' # 3. dealTargetSheet() 検出されたファイルの1シートごとに行いたい処理を実装する ' # 4. ブック毎後処理() 検出されたファイルのブックごとに行いたい後処理を実装する ' # 5. editResults() 実行結果について、ファイルに出力する前に編集したい場合に実装する(重複の削除、ソート等) ' # 6. setStyle() ファイルに出力した後の実行結果を編集したい場合に実装する(ハイパーリンクの設定等) ' # 7. 後処理() 処理実行後に1度だけ実行したい処理を実装する ' # ' ##################################################################################################################### ' ' ********************************************************************************************************************* ' 機能 :固有処理側の前処理 ' ********************************************************************************************************************* ' Function 前処理(targetSheet As Worksheet) ' ----------------------------------------------------------------------------------------------------------------- ' 初期化処理 ' ----------------------------------------------------------------------------------------------------------------- ' 処理した件数の初期化 resultCount = 0 ' ----------------------------------------------------------------------------------------------------------------- ' 前処理 ' ----------------------------------------------------------------------------------------------------------------- ' 処理対象の検索文言リストを取得する。 ' 固有処理(マクロの呼び出し元)側のパス情報を取得する。 searchArgList = タイトル名指定でリスト値を取得(TITLE_NAME_BY_SEARCH_WORD, targetSheet) End Function ' ********************************************************************************************************************* ' 機能 :検出されたファイルのブックごとに行いたい処理を実装する(シート毎の処理呼び出しが不要かの判定値(boolean)を返却する) ' ********************************************************************************************************************* ' Function dealTargetWorkbook(fileName As Variant, targetWB As Workbook, ByRef results() As Variant) As Boolean End Function ' ********************************************************************************************************************* ' 機能 :検出されたファイルの1シートごとに行いたい処理を実装する ' ********************************************************************************************************************* ' Function dealTargetSheet(fileName As Variant, targetSheet As Worksheet, ByRef results() As Variant) Dim FSO Set FSO = CreateObject("Scripting.FileSystemObject") Dim searchArg As Variant Dim targetWB As Workbook Dim ShapesInfoList As Variant Dim ShapesInf As Variant ' ----------------------------------------------------------------------------------------------------------------- ' 処理 ' ----------------------------------------------------------------------------------------------------------------- ' 指定された検索文言リストの文字列の検索結果を収集する。 ' 対象シートの検索結果を「FoundAddr」に格納する。 Dim firstAddress As String Dim FoundCell As Range ' 検索文言リスト分ループ For Each searchArg In searchArgList ' 検索文言がない場合、次の検索文言を処理する If "" = searchArg Then GoTo ContinueBySearchArg End If ' <セルの検索> Set FoundCell = targetSheet.UsedRange.Find(what:=searchArg, LookIn:=xlValues, _ LookAt:=xlPart, MatchCase:=False, MatchByte:=False) ' セルへの検索結果がない場合 If FoundCell Is Nothing Then ' 検索結果がなかった場合次の検索文言を処理する GoTo GotoCellSearchEnd End If firstAddress = FoundCell.Address ' 検索結果のアドレスを配列に格納 Do ' 結果を格納する Call reDimResult(RESULT_COL_LENGTH, results) ' 結果保持の配列作成 results(0, resultCount) = searchArg ' 検索文言 results(1, resultCount) = FSO.GetParentFolderName(fileName) ' フォルダ名 results(2, resultCount) = FSO.GetFileName(fileName) ' ファイル名 results(3, resultCount) = targetSheet.Name ' シート名 results(4, resultCount) = FoundCell.Address(False, False) ' 座標 results(5, resultCount) = "セル" ' セル/オートシェイプ results(6, resultCount) = FoundCell.Value ' 文字列 resultCount = resultCount + 1 Set FoundCell = targetSheet.UsedRange.FindNext(After:=FoundCell) Loop Until FoundCell.Address = firstAddress GotoCellSearchEnd: ' <オートシェイプの検索> ShapesInfoList = getShapesProperty(targetSheet) Dim i As Integer Dim textValue As Variant i = 0 ' 検索文言リスト分ループ If Not IsEmpty(ShapesInfoList) Then For i = LBound(ShapesInfoList) To UBound(ShapesInfoList) textValue = ShapesInfoList(i, 2) If Not IsEmpty(textValue) And InStr(textValue, searchArg) Then ' 結果を格納する Call reDimResult(RESULT_COL_LENGTH, results) ' 結果保持の配列作成 results(0, resultCount) = searchArg ' 検索文言 results(1, resultCount) = FSO.GetParentFolderName(fileName) ' フォルダ名 results(2, resultCount) = FSO.GetFileName(fileName) ' ファイル名 results(3, resultCount) = targetSheet.Name ' シート名 results(4, resultCount) = ShapesInfoList(i, 7) ' 座標 results(5, resultCount) = "オートシェイプ" ' セル/オートシェイプ results(6, resultCount) = textValue ' 文字列 resultCount = resultCount + 1 End If Next i End If ContinueBySearchArg: Next End Function ' ********************************************************************************************************************* ' 機能 :検出されたファイルのブックごとに行いたい後処理を実装する ' ********************************************************************************************************************* ' Function ブック毎後処理(fileName As Variant, targetWB As Workbook, ByRef results() As Variant) As Long End Function ' ********************************************************************************************************************* ' 機能 :実行結果について、ファイルに出力する前に編集したい場合に実装する(重複の削除、ソート等) ' ********************************************************************************************************************* ' Function editResults(ByRef var変換元() As Variant) As Variant End Function ' ********************************************************************************************************************* ' 機能 :ファイルに出力した後の実行結果を編集したい場合に実装する(ハイパーリンクの設定等) ' ********************************************************************************************************************* ' Sub setStyle(ByRef targetSheet As Worksheet) Dim i, MaxRow, MaxCol As Long With targetSheet MaxRow = .UsedRange.Find("*", , xlFormulas, , xlByRows, xlPrevious).Row MaxCol = .UsedRange.Find("*", , xlFormulas, , xlByColumns, xlPrevious).Column ' 書式コピー .Range(Cells(2, 1), Cells(2, MaxCol)).Copy .Range(Cells(2 + 1, 1), Cells(MaxRow, MaxCol)).PasteSpecial (xlPasteFormats) For i = 2 To MaxRow ' ハイパーリンク設定 Dim strHyperLink As String strHyperLink = editHYPERLINK数式(.Cells(i, 2), .Cells(i, 3), .Cells(i, 4), .Cells(i, 5)) .Range(.Cells(i, 5), .Cells(i, 5)).Value = strHyperLink ' 赤文字 ' Call 検索該当文字の赤文字化(.Range(Cells(i, 7), Cells(i, 7)), Cells(i, 1)) Next End With End Sub ' ********************************************************************************************************************* ' 機能 :処理実行後に1度だけ実行したい処理を実装する ' ********************************************************************************************************************* ' Function 後処理(targetSheet As Worksheet) End Function ' ##################################################################################################################### ' # ' # テンプレートメソッド以外のメソッド ' # ' ##################################################################################################################### ' ' なし
Option Explicit ' --------------------------------------------------------------------------------------------------------------------- ' 定数 ' --------------------------------------------------------------------------------------------------------------------- 'パスのデリミタ Public Const PATH_DELIMITER = "\" ' ファイル名、拡張子のデリミタ Public Const FILE_DELIMITER = "." ' ファイル操作情報 Public Type ファイル操作情報 フルパス_ファイル名 As String フルパス As String 親ディレクトリまでのフルパス As String 対象ディレクトリ名 As String 対象ファイル名 As String 対象ファイル情報() As String End Type ' 対象の拡張子(モジュール) Public Const FILE_EXTENSION_OF_MODULE = "bas,cls,frm" ' ファイルCLOSE状態区分 Public Enum ファイルCLOSE方法区分 保存しないで閉じる = 0 保存して閉じる = 1 保存しないで閉じない = 2 保存して閉じない = 3 処理中断 = 99 End Enum ' --------------------------------------------------------------------------------------------------------------------- ' 変数 ' --------------------------------------------------------------------------------------------------------------------- ' ルートパス作成済フラグ Private rootPathMaked As Boolean ' ##################################################################################################################### ' # ' # アクセサ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' * 機能 :ルートパス作成済みフラグを設定する ' ********************************************************************************************************************* ' Public Function getRootPathMaked() As Boolean getRootPathMaked = rootPathMaked End Function ' ********************************************************************************************************************* ' * 機能 :ルートパス作成済みフラグを取得する ' ********************************************************************************************************************* ' Public Function setRootPathMaked(isMaked As Boolean) rootPathMaked = isMaked End Function ' ##################################################################################################################### ' # ' # ファイル操作ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' * 機能 :パス(パス&ファイル)の存在チェック ' * 引数 :directoryPath パス(または、パス&ファイル) ' * 戻り値:チェック結果(パス存在時は1、ファイル存在時は2、パスもファイルも存在しない場合は-1) ' ********************************************************************************************************************* ' Function isDirectoryExist(directoryPath As String) As Long Dim FSO Set FSO = CreateObject("Scripting.FileSystemObject") If True = FSO.FileExists(directoryPath) Then isDirectoryExist = 2 ElseIf True = FSO.FolderExists(directoryPath) Then isDirectoryExist = 1 Else isDirectoryExist = -1 End If End Function ' ********************************************************************************************************************* ' * 機能 :パス配下の階層全てのディレクトリを処理する ' * 引数 :directoryPath パス ' * 戻り値:実行結果(カレントディレクトリを含む、配下のディレクトリ名の配列 ' ********************************************************************************************************************* ' Function doRepeat(ByVal directoryPath As String, ByVal fileExtensions As Variant, _ ByRef fileNames() As String, Optional ByVal recursive As Boolean = False) ' 検索結果 Dim buf As String, msg As String, dirName As Variant ' 配下のパス情報 Dim directoryPathBySub As String directoryPathBySub = directoryPath ' 直下のディレクトリ存在可否フラグ Dim isExistDir As Boolean isExistDir = False Dim dirNames() As String Dim resultArray As Variant If "" <> directoryPath Then ' ディレクトリ移動 ChDir directoryPath ' ------------------------------------------------------------------------------------------------------------- ' 直下のファイル名を全て取得 ' ------------------------------------------------------------------------------------------------------------- Call getFileNames(directoryPath, fileExtensions, fileNames) If recursive Then ' --------------------------------------------------------------------------------------------------------- ' 直下のディレクトリ名を全て取得 ' --------------------------------------------------------------------------------------------------------- dirNames = getDirNames(directoryPath) ' --------------------------------------------------------------------------------------------------------- ' 取得したディレクトリ名1つずつ再帰的に処理する。 ' --------------------------------------------------------------------------------------------------------- If Not Not dirNames Then For Each dirName In dirNames Call doRepeat(dirName, fileExtensions, fileNames, True) Next End If End If End If End Function ' ********************************************************************************************************************* ' * 機能 :パス直下のファイル名を全て取得 ' * 引数 :directoryPath パス ' * 戻り値:実行結果(カレントディレクトリ直下のディレクトリ名の配列。) ' ********************************************************************************************************************* ' Function getFileNames(directoryPath As String, fileExtensions As Variant, ByRef fileNames() As String) Dim fileName As String, msg As String Dim fileNameSize As Integer Dim fileExtension As Variant ' ディレクトリ移動 ChDir directoryPath ' ----------------------------------------------------------------------------------------------------------------- ' 直下のファイル名を全て取得 ' ----------------------------------------------------------------------------------------------------------------- fileName = Dir(directoryPath & "\" & "*.*") Do While fileName <> "" ' ファイル名取得 For Each fileExtension In fileExtensions If InStr(1, UCase(fileName), UCase(fileExtension)) > 0 Then ' フルパス&ファイル名を追加格納。 Call 一次配列に値を追加(fileNames, directoryPath & "\" & fileName) Exit For End If Next fileName = Dir() Loop End Function ' ********************************************************************************************************************* ' * 機能 :パス直下のディレクトリ名を全て取得 ' * 引数 :directoryPath パス ' * 戻り値:実行結果(カレントディレクトリ直下のディレクトリ名の配列。) ' ********************************************************************************************************************* ' Function getDirNames(directoryPath As String) As String() Dim buf As String Dim dirNames() As String ' ディレクトリ移動 ChDir directoryPath buf = Dif(directoryPath & "\" & "*.*", vbDirectory) Do While buf <> "" ' ディレクトリ名取得 If GetAttr(directoryPath & "\" & buf) And vbDirectory Then If buf <> "." And buf <> ".." Then ' ディレクトリ名を追加格納。 Call 一次元配列に値を追加(dirNames, directoryPath & "\" & buf) End If End If buf = Dir() Loop getDirNames = dirNames End Function ' ********************************************************************************************************************* ' * 機能 :対象ディレクトリを作成する(対象パスが未存在、作成ディレクトリ名が存在した場合は処理中断) ' ********************************************************************************************************************* ' Function ディレクトリ作成(ByVal ルートパス As String, ByVal 処理日時 As String, ByVal 相対パス As String) Dim dirCheck As Long ' ルートパスの存在チェック dirCheck = isDirectoryExist(CStr(ルートパス & 処理日時)) ' 対象パスが未設定の場合(ルートパス作成時) If "" = 相対パス Then ' 処理日時が設定済の場合、ルートパスが作成済であれば処理中断とする If "" <> 処理日時 Then If 0 < dirCheck And False = getRootPathMaked() Then MsgBox "以下のディレクトリは既に存在するため処理を中断します。" + Chr(10) + "「" + ルートパス & 処理日時 + "」" End End If End If End If ' ディレクトリ作成 dirCheck = isDirectoryExist(CStr(ルートパス & 処理日時 & PATH_DELIMITER & 相対パス)) If 0 > dirCheck Then MkDir ルートパス & 処理日時 & PATH_DELIMITER & 相対パス Call setRootPathMaked(True) End If End Function
Option Explicit ' --------------------------------------------------------------------------------------------------------------------- ' 定数 ' --------------------------------------------------------------------------------------------------------------------- Public Const TITLE_NAME_PREFIX = "▼" ' --------------------------------------------------------------------------------------------------------------------- ' 変数 ' --------------------------------------------------------------------------------------------------------------------- Dim var開始時刻 As Variant ' ##################################################################################################################### ' # ' # ログ系ユーティリティ ' # ' ##################################################################################################################### Sub log(ByVal strメッセージ As String) Debug.Print Format(Now(), "HH:mm:ss ") & strメッセージ End Sub ' ##################################################################################################################### ' # ' # ステータスバー操作系ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' * 機能 :ステータスバーに表示する処理時間を初期化する ' ********************************************************************************************************************* ' Sub init開始時刻() var開始時刻 = Now() End Sub ' ********************************************************************************************************************* ' * 機能 :処理時間の開始時刻を取得する ' ********************************************************************************************************************* ' Function get開始時刻() get開始時刻 = var開始時刻 End Function ' ********************************************************************************************************************* ' * 機能 :処理時間を HH:mm:ss 形式で取得する ' ********************************************************************************************************************* ' Function get処理時刻() get処理時刻 = Format(Now() - var開始時刻, "HH:mm:ss") End Function ' ********************************************************************************************************************* ' * 機能 :ステータスバーに経過時間付でメッセージを表示する ' ********************************************************************************************************************* ' Sub setステータスバー(ByVal strメッセージ As String) If IsEmpty(var開始時刻) Then var開始時刻 = Now() End If Application.StatusBar = get処理時刻() & " " & strメッセージ End Sub ' ##################################################################################################################### ' # ' # ブック、シート操作系ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' * 機能 :引数で渡されたシート名以外のシートを削除する ' ********************************************************************************************************************* ' ' Function 不要シート削除(対象ブック情報 As Workbook, ByVal 残すシート名 As String) Dim 前状態 As Boolean 前状態 = Application.DisplayAlerts Application.DisplayAlerts = False Dim ws As Worksheet For Each ws In 対象ブック情報.Worksheets If ws.Name <> 残すシート名 Then Worksheets(ws.Name).Delete End If Next ws Application.DisplayAlerts = 前状態 End Function ' ##################################################################################################################### ' # ' # ダイアログ操作系ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' * 機能 :処理続行 or 中止確認ダイアログを表示する ' ********************************************************************************************************************* ' Function 処理続行判断(message As String) Dim rc As VbMsgBoxResult rc = MsgBox(message + Chr(10) + "処理を続行しますか?", vbYesNo, vbQuestion) If rc = vbYes Then MsgBox "処理を続けます", vbInformation Else MsgBox "処理を中止しました。", vbCritical ' マクロの実行中止 End End If End Function ' ##################################################################################################################### ' # ' # オートシェイプ操作系ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' 機能名:対象シート上にあるオブジェクトおnプロパティを取得する ' 戻り :getShapesProperty as String(2, n) ' (0, n) type ' (1, n) name ' (2, n) TextFrame.Characters.text ' (3, n) Left ' (4, n) Top ' (5, n) Width ' (6, n) Height ' (7, n) TopLeftCell.Address(False, False) ' (8, n) TopLeftCell.row ' (9, n) TopLeftCell.Column ' (10, n) BottomRightCell.Address(False, False) ' (11, n) BottomRightCell.row ' (12, n) BottomRightCell.Column ' ' ********************************************************************************************************************* ' Function getShapesProperty(ByRef targetSheet As Worksheet, Optional ByVal objType As Long = -999, Optional ByVal formCtlType As Long = -999) As Variant Dim ret As Variant Dim i As Long Dim obj As Variant ' 配列の作成。 i = 0 For Each obj In targetSheet.Shapes ' FORMコントロールの場合 If obj.Type = objType Then ' 渡されたフォームコントロールタイプが一致した場合、カウントアップ If obj.FormControlType = formCtlType Then i = i + 1 End If ' 指定なし又は、それ以外のオートシェイプ ElseIf objType = -999 Or obj.Type = objType Then i = i + 1 End If Next ' 対象のオートシェイプがみつかった場合のみ、そのオブジェクトの格納を行う。 If 0 <> i Then ReDim ret(i - 1, 12) ' 配列の作成 i = 0 ' オブジェクト情報の設定 For Each obj In targetSheet.Shapes ' formコントロールの場合 If obj.Type = objType Then ' 渡されたフォームコrントロールタイプが一致した場合、値を取得する。 If obj.FormControlType = formCtlType Then ret(i, 0) = obj.Type ret(i, 1) = obj.AlternativeText ' TextFrameプロパティが使用できない(レイアウト枠がない)オブジェクトは除外 On Error Resume Next ret(i, 2) = obj.ControlFormat.Value ret(i, 3) = obj.Left ret(i, 4) = obj.Top ret(i, 5) = obj.Width ret(i, 6) = obj.Height ret(i, 7) = obj.TopLeftCell.Address(False, False) ret(i, 8) = obj.TopLeftCell.Row ret(i, 9) = obj.TopLeftCell.Column ret(i, 10) = obj.Left.BottomRightCell.Address(False, False) ret(i, 11) = obj.Left.BottomRightCell.Row ret(i, 12) = obj.Left.BottomRightCell.Column i = i + 1 End If ' 指定なし又は、それ以外のオートシェイプなどの場合 ElseIf objType = -999 Or obj.Type = objType Then ret(i, 0) = obj.Type ret(i, 1) = obj.AlternativeText ' TextFrameプロパティが使用できない(レイアウト枠がない)オブジェクトは除外 On Error Resume Next ret(i, 2) = obj.TextFrame.Characters.Text ret(i, 3) = obj.Left ret(i, 4) = obj.Top ret(i, 5) = obj.Width ret(i, 6) = obj.Height ret(i, 7) = obj.TopLeftCell.Address(False, False) ret(i, 8) = obj.TopLeftCell.Row ret(i, 9) = obj.TopLeftCell.Column ret(i, 10) = obj.Left.BottomRightCell.Address(False, False) ret(i, 11) = obj.Left.BottomRightCell.Row ret(i, 12) = obj.Left.BottomRightCell.Column i = i + 1 End If Next End If getShapesProperty = ret End Function ' ##################################################################################################################### ' # ' # 配列操作系ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' 機能 :引数が配列か判定し、配列の場合は空かどうかも判定する ' 引数 :varArray 配列 ' 戻り値:判定結果(1:配列/0:空の配列/-1:配列じゃない) ' ********************************************************************************************************************* ' Public Function IsArrayEx(varArray As Variant) As Long On Error GoTo ERROR_ If IsArray(varArray) Then IsArrayEx = IIf(UBound(varArray) >= 0, 1, 0) Else IsArrayEx = -1 End If Exit Function ERROR_: If Err.Number = 9 Then IsArrayEx = 0 End If End Function ' ********************************************************************************************************************* ' 機能 :実行結果を保持する二次元配列変数を定義するFunction ' ********************************************************************************************************************* ' Function reDimResult(ByVal topLevelElementSize As Integer, ByRef results() As Variant) Select Case IsArrayEx(results) Case 1 ' resultsが初期化済の場合 ' 現在のレコード数 + 1行領域を確保 ReDim Preserve results(topLevelElementSize, UBound(results, 2) + 1) Case 0 ' resultsが1度も初期化されていない場合 ' 1行領域を確保 ReDim Preserve results(topLevelElementSize, 0) End Select End Function ' ********************************************************************************************************************* ' 機能 :一次元配列に新たな要素を追加する ' ********************************************************************************************************************* ' Function 一次配列に値を追加(ByRef valueList As Variant, ByVal 追加設定値 As String) ' ファイル名を取得する Select Case IsArrayEx(valueList) Case 1 ReDim Preserve valueList(UBound(valueList) + 1) Case 0 ReDim Preserve valueList(0) End Select ' 追加したリストに、設定値を格納。 valueList(UBound(valueList)) = 追加設定値 End Function ' ********************************************************************************************************************* ' 機能 :二次元配列の行と列を入れ替える ' ********************************************************************************************************************* ' Function 二次元配列行列逆転(ByRef var二次元配列 As Variant) Dim var逆転後配列 As Variant ReDim var逆転後配列( _ LBound(var二次元配列, 2) To UBound(var二次元配列, 2), _ LBound(var二次元配列) To UBound(var二次元配列)) Dim i, j As Long For i = LBound(var二次元配列) To UBound(var二次元配列, 2) For j = LBound(var二次元配列) To UBound(var二次元配列) var逆転後配列(i, j) = var二次元配列(j, i) Next Next 二次元配列行列逆転 = var逆転後配列 End Function ' ##################################################################################################################### ' # ' # 装飾系ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' 機能 :対象セルにハイパーリンク数式を適用する ' ********************************************************************************************************************* ' Public Function editHYPERLINK数式( _ ByVal strフォルダ名 As String, _ ByVal strファイル名 As String, _ ByVal strシート名 As String, _ ByVal str座標 As String) As String editHYPERLINK数式 = _ "=HYPERLINK(""[" & strフォルダ名 & "\" & strファイル名 & "]" & _ strシート名 & "!" & str座標 & """,""" & str座標 & """)" End Function ' ********************************************************************************************************************* ' 機能 :対象セル範囲内で検索文字列に該当した文字列を赤太文字にする ' ********************************************************************************************************************* ' Function 検索該当文字の赤太文字化(prmRange As Range, prmTargetString As String) Dim txt As String Dim i, m As Integer Dim targetRange As Range If prmTargetString = "" Then Exit Function End If For Each targetRange In prmRange txt = targetRange.Value m = Len(prmTargetString) i = InStr(1, txt, prmTargetString) Do Until i = 0 With prmRange.Characters(i, m) .Font.Bold = True .Font.ColorIndex = 3 End With i = InStr(i + 1, txt, prmTargetString) Loop Next Set targetRange = Nothing End Function ' ##################################################################################################################### ' # ' # シート情報取得系ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' 機能 :タイトル名指定でリスト値を取得 ' ※リスト値がなかった場合、配列の要素数1(値は空)が返却されます。 ' ********************************************************************************************************************* ' Function タイトル名指定でリスト値を取得(titleName As String, targetSheet As Worksheet) As Variant Dim targetRangeList As Range Dim targetVariantList As Variant Set targetRangeList = タイトル名指定でリスト値のRange情報を取得(titleName, targetSheet) ' 配列か判定 If targetRangeList.Count = 1 Then targetVariantList = Array(targetRangeList.Item(1).Value) Else targetVariantList = targetRangeList.Value End If タイトル名指定でリスト値を取得 = targetVariantList End Function ' ********************************************************************************************************************* ' 機能 :タイトル名指定でリスト値のRange情報を取得 ' ※リスト値がなかった場合、リスト値エリアの1行目(値は空)のRange情報が返却されます。 ' ********************************************************************************************************************* ' Function タイトル名指定でリスト値のRange情報を取得(titleName As String, targetSheet As Worksheet) As Range ' 検索ヒット数 Dim matchCount As Long Dim checkValue As String ' シート内にタイトル名が複数設定されていない事を確認する。 matchCount = WorksheetFunction.CountIf(targetSheet.UsedRange, titleName) If 1 <> matchCount Then MsgBox "タイトル「" & titleName & "」が複数見つかったため、処理を中断しました。" End End If ' タイトル名のRange情報を取得 Dim FoundCell As Range Set FoundCell = targetSheet.UsedRange.Find(what:=titleName, LookIn:=xlValues, _ LookAt:=xlPart, MatchCase:=False, MatchByte:=False) Dim i, MaxRow, MaxCol As Long ' タイトルに対するリスト値を取得(空白行込み) With targetSheet With .Range(.Cells(FoundCell.Row, FoundCell.Column), .Cells(Rows.Count, FoundCell.Column)) MaxRow = .Find("*", , xlFormulas, , xlByRows, xlPrevious).Row MaxCol = .Find("*", , xlFormulas, , xlByColumns, xlPrevious).Column End With ' MaxRowを、空白行より一行↑のリスト値の行数に設定する。 For i = 1 To (MaxRow - FoundCell.Row) checkValue = .Cells(FoundCell.Row + i, MaxCol).Value If "" = checkValue Or InStr(1, checkValue, TITLE_NAME_PREFIX) > 0 Then If 1 = i Then Call 処理続行判断("タイトル名「" + titleName + "」に対するリスト値が設定されていません。") MaxRow = FoundCell.Row + 1 Else MaxRow = FoundCell.Row + i - 1 End If Exit For End If Next ' リスト値を返却 Set タイトル名指定でリスト値のRange情報を取得 = _ targetSheet.Range(.Cells((FoundCell.Row + 1), FoundCell.Column), .Cells(MaxRow, MaxCol)) End With End Function
FileOperationUtil
Attribute VB_Name = "FileOperationUtil" Option Explicit ' --------------------------------------------------------------------------------------------------------------------- ' 定数 ' --------------------------------------------------------------------------------------------------------------------- 'パスのデリミタ Public Const PATH_DELIMITER = "\" ' ファイル名、拡張子のデリミタ Public Const FILE_DELIMITER = "." ' ファイル操作情報 Public Type ファイル操作情報 フルパス_ファイル名 As String フルパス As String 親ディレクトリまでのフルパス As String 対象ディレクトリ名 As String 対象ファイル名 As String 対象ファイル情報() As String End Type ' 対象の拡張子(モジュール) Public Const FILE_EXTENSION_OF_MODULE = "bas,cls,frm" ' ファイルCLOSE状態区分 Public Enum ファイルCLOSE方法区分 保存しないで閉じる = 0 保存して閉じる = 1 保存しないで閉じない = 2 保存して閉じない = 3 処理中断 = 99 End Enum ' --------------------------------------------------------------------------------------------------------------------- ' 変数 ' --------------------------------------------------------------------------------------------------------------------- ' ルートパス作成済フラグ Private rootPathMaked As Boolean ' ##################################################################################################################### ' # ' # アクセサ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' * 機能 :ルートパス作成済みフラグを設定する ' ********************************************************************************************************************* ' Public Function getRootPathMaked() As Boolean getRootPathMaked = rootPathMaked End Function ' ********************************************************************************************************************* ' * 機能 :ルートパス作成済みフラグを取得する ' ********************************************************************************************************************* ' Public Function setRootPathMaked(isMaked As Boolean) rootPathMaked = isMaked End Function ' ##################################################################################################################### ' # ' # ファイル操作ユーティリティ ' # ' ##################################################################################################################### ' ********************************************************************************************************************* ' * 機能 :パス(パス&ファイル)の存在チェック ' * 引数 :directoryPath パス(または、パス&ファイル) ' * 戻り値:チェック結果(パス存在時は1、ファイル存在時は2、パスもファイルも存在しない場合は-1) ' ********************************************************************************************************************* ' Function isDirectoryExist(directoryPath As String) As Long Dim FSO Set FSO = CreateObject("Scripting.FileSystemObject") If True = FSO.FileExists(directoryPath) Then isDirectoryExist = 2 ElseIf True = FSO.FolderExists(directoryPath) Then isDirectoryExist = 1 Else isDirectoryExist = -1 End If End Function ' ********************************************************************************************************************* ' * 機能 :フォルダが存在しなかったら作成する ' ********************************************************************************************************************* ' Function mkdirIFNotExist(txtフォルダ名 As String) If Dir(txtフォルダ名, vbDirectory) = "" Then mkdir txtフォルダ名 End If End Function ' ********************************************************************************************************************* ' * 機能 :パス配下の階層全てのディレクトリを処理する ' * 引数 :directoryPath パス ' * 戻り値:実行結果(カレントディレクトリを含む、配下のディレクトリ名の配列 ' ********************************************************************************************************************* ' Function doRepeat(ByVal directoryPath As String, ByVal fileExtensions As Variant, _ ByRef fileNames() As String, Optional ByVal recursive As Boolean = False) ' 検索結果 Dim buf As String, msg As String, dirName As Variant ' 配下のパス情報 Dim directoryPathBySub As String directoryPathBySub = directoryPath ' 直下のディレクトリ存在可否フラグ Dim isExistDir As Boolean isExistDir = False Dim dirNames() As String Dim resultArray As Variant If "" <> directoryPath Then ' ディレクトリ移動 ChDir directoryPath ' ------------------------------------------------------------------------------------------------------------- ' 直下のファイル名を全て取得 ' ------------------------------------------------------------------------------------------------------------- Call getFileNames(directoryPath, fileExtensions, fileNames) If recursive Then ' --------------------------------------------------------------------------------------------------------- ' 直下のディレクトリ名を全て取得 ' --------------------------------------------------------------------------------------------------------- dirNames = getDirNames(directoryPath) ' --------------------------------------------------------------------------------------------------------- ' 取得したディレクトリ名1つずつ再帰的に処理する。 ' --------------------------------------------------------------------------------------------------------- If Not Not dirNames Then For Each dirName In dirNames Call doRepeat(dirName, fileExtensions, fileNames, True) Next End If End If End If End Function ' ********************************************************************************************************************* ' * 機能 :パス直下のファイル名を全て取得 ' * 引数 :directoryPath パス ' * 戻り値:実行結果(カレントディレクトリ直下のディレクトリ名の配列。) ' ********************************************************************************************************************* ' Function getFileNames(directoryPath As String, fileExtensions As Variant, ByRef fileNames() As String) Dim fileName As String, msg As String Dim fileNameSize As Integer Dim fileExtension As Variant ' ディレクトリ移動 ChDir directoryPath ' ----------------------------------------------------------------------------------------------------------------- ' 直下のファイル名を全て取得 ' ----------------------------------------------------------------------------------------------------------------- fileName = Dir(directoryPath & "\" & "*.*") Do While fileName <> "" ' ファイル名取得 For Each fileExtension In fileExtensions If InStr(1, UCase(fileName), UCase(fileExtension)) > 0 Then ' フルパス&ファイル名を追加格納。 Call 一次配列に値を追加(fileNames, directoryPath & "\" & fileName) Exit For End If Next fileName = Dir() Loop End Function ' ********************************************************************************************************************* ' * 機能 :パス直下のディレクトリ名を全て取得 ' * 引数 :directoryPath パス ' * 戻り値:実行結果(カレントディレクトリ直下のディレクトリ名の配列。) ' ********************************************************************************************************************* ' Function getDirNames(directoryPath As String) As String() Dim buf As String Dim dirNames() As String ' ディレクトリ移動 ChDir directoryPath buf = Dif(directoryPath & "\" & "*.*", vbDirectory) Do While buf <> "" ' ディレクトリ名取得 If GetAttr(directoryPath & "\" & buf) And vbDirectory Then If buf <> "." And buf <> ".." Then ' ディレクトリ名を追加格納。 Call 一次元配列に値を追加(dirNames, directoryPath & "\" & buf) End If End If buf = Dir() Loop getDirNames = dirNames End Function ' ********************************************************************************************************************* ' * 機能 :対象ディレクトリを作成する(対象パスが未存在、作成ディレクトリ名が存在した場合は処理中断) ' ********************************************************************************************************************* ' Function ディレクトリ作成(ByVal ルートパス As String, ByVal 処理日時 As String, ByVal 相対パス As String) Dim dirCheck As Long ' ルートパスの存在チェック dirCheck = isDirectoryExist(CStr(ルートパス & 処理日時)) ' 対象パスが未設定の場合(ルートパス作成時) If "" = 相対パス Then ' 処理日時が設定済の場合、ルートパスが作成済であれば処理中断とする If "" <> 処理日時 Then If 0 < dirCheck And False = getRootPathMaked() Then MsgBox "以下のディレクトリは既に存在するため処理を中断します。" + Chr(10) + "「" + ルートパス & 処理日時 + "」" End End If End If End If ' ディレクトリ作成 dirCheck = isDirectoryExist(CStr(ルートパス & 処理日時 & PATH_DELIMITER & 相対パス)) If 0 > dirCheck Then mkdir ルートパス & 処理日時 & PATH_DELIMITER & 相対パス Call setRootPathMaked(True) End If End Function