- ベストアンサー
Excel VBAで表のフォーマットを変えたい
- 弊社では、電子スケジュール管理ソフトを使っています。現在、予定表をExcelに貼り付けて編集していますが、VBAを用いて編集作業を簡便化したいです。
- 現在の表はあまり使いやすくない状態で、日付と予定が別のセルに格納されており、名前で並べ替えもできません。整理したいです。
- VBAの知識がほとんどないため、断片的な情報でも構いません。VBAの得意な方にご教授いただけないでしょうか?
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
とりあえずこんな感じで、 Sub Macro1() Dim fromSheet As Worksheet ' 変換元シート Dim fromTitleRow As Long ' 変換元、日付の行(1行目) Dim fromNameCol As Long ' 変換元、名前の列(1列目) Dim fromStartRow As Long ' 変換元、スケジュールの開始行 Dim fromStartCol As Long ' 変換元、スケジュールの開始列 Dim fromEndCol As Long ' 変換元、スケジュール終了列 Dim fromRow As Long ' 変換元、作業を行う行 Dim fromCol As Long ' 変換元、作業を行う列 Dim toSheet As Worksheet ' 変換先シート Dim toTitleRow As Long ' 変換先、日付の行(1行目) Dim toNameCol As Long ' 変換先、名前の列(1列目) Dim toRow As Long ' 変換先、作業を行う行 Dim toCol As Long ' 変換先、作業を行う列 Dim ConnectCount As Long ' 連結数 Dim workRow As Long ' 作業を行う行 Dim addCRLF As String ' 改行処理用 ' コピペして貼りつけたシート(変換元)を fromSheet とする ' 日付のある行を1行目とする、名前のある列を1列目とする Set fromSheet = Worksheets("Sheet1") fromTitleRow = 1 fromNameCol = 1 ' 整形した結果のシート(変換先)を toSheet とする ' 日付のある行を1行目とする、名前のある列を1列目とする Set toSheet = Worksheets("Sheet2") toTitleRow = 1 toNameCol = 1 ' 変換元 ' スケジュールの開始行=日付の行+1 ' スケジュールの開始列=名前の列+1 ' スケジュールの終了列=最初の日付のセルから[CTRL]+[→]で移動した先の列 fromStartRow = fromTitleRow + 1 fromStartCol = fromNameCol + 1 fromEndCol = fromSheet.Cells(fromStartRow, fromStartCol).End(xlToRight).Column ' 出力先のシートをクリアする ' Cells でシート全体を指定しています ' 範囲で指定する場合、(A1セルから F65536セル迄なら) ' toSheet.Range("A1:F65536").~ のように変更します toSheet.Cells.ClearContents toSheet.Cells.Borders.LineStyle = xlNone toSheet.Cells.Interior.ColorIndex = xlNone ' 日付分ループして、日付を toSheetにコピーします toCol = toNameCol + 1 For fromCol = fromStartCol To fromEndCol toSheet.Cells(toTitleRow, toCol).Value = fromSheet.Cells(fromTitleRow, fromCol).Value toCol = toCol + 1 Next fromCol ' 作業を行う行を、スケジュールの開始行にしてループ開始 ' ループは名前が無ければ終了 fromRow = fromStartRow toRow = toTitleRow + 1 Do While (Trim(fromSheet.Cells(fromRow, fromNameCol).Value) <> "") ' toSheet 側に名前をコピーします toSheet.Cells(toRow, toNameCol).Value = _ fromSheet.Cells(fromRow, fromNameCol).Value ' 名前セルは連結されているので、何個連結しているかを求める、 ' 1つの予定は、空欄、時刻、予定の3行で記述されているため、 ' ループする際は3行とびで行う ConnectCount = fromSheet.Cells(fromRow, fromNameCol).MergeArea.Count ' 日付分ループ toCol = toNameCol + 1 For fromCol = fromStartCol To fromEndCol ' toSheet側のスケジュールのセルをクリアします toSheet.Cells(toRow, fromCol) = "" ' 最終行にCRLFを付けない処理 addCRLF = "" ' 連結数分ループ(3行毎) For workRow = 0 To ConnectCount Step 3 ' 予定をがなければ、その日のループは終了 ' 空欄、時刻、予定の3行なので、+2行目にある予定の文字が空欄か確認 If (Trim(fromSheet.Cells(fromRow + workRow + 2, fromCol).Value) = "") Then Exit For End If ' toSheet にスケジュールを追記 ' +1 が 時刻の行を示す ' +2 が 予定の行を示す toSheet.Cells(toRow, toCol).Value = toSheet.Cells(toRow, toCol).Value _ & addCRLF _ & fromSheet.Cells(fromRow + workRow + 1, fromCol).Value & vbCrLf _ & fromSheet.Cells(fromRow + workRow + 2, fromCol).Value addCRLF = vbCrLf Next workRow toCol = toCol + 1 Next fromCol ' 次の人の行に移動 toRow = toRow + 1 fromRow = fromRow + ConnectCount Loop ' 終了処理 Set toSheet = Nothing Set fromSheet = Nothing End Sub
お礼
大感謝です。 これ、発注したらかなりのコストがかかっていたと思います。 もちろん、大満足です。 どうもありがとうございました! もしお時間がありましたら、第二の願いである、決められた名前順に並び替えるロジックも教えていただければ幸いです。 (VBAソースは別に構えていただいて結構です) ホント、助かりました。