タスク整理マクロ

 Microsoft Projectのタスクの切り方がまずかったから、進捗報告のためにExcel上でデータを操作するためのマクロです。これもそのまま使えるわけではありませんが、マクロでの検索の使い方などが参考になるため、掲載しておきます。

Sub main()

   Dim c As Object

   Dim sSlot() As String
   Dim sRyoiki() As String
   Dim sTitle() As String
   Dim sAddon() As String
   Dim sKinou() As String
   Dim sBefore() As String
   Dim sAfter() As String

   Dim lRow As Long
   Dim lCol As Long
   Dim lIndex As Long

   Dim sRange As String
   Dim sSheet As String
   Dim sAddress As String

   sSheet = "作業用シート"
   sRange = "E2:E65536"

   ReDim sSlot(4)
   sSlot(1) = "スロット1"
   sSlot(2) = "スロット2"
   sSlot(3) = "スロット3"
   sSlot(4) = "スロット4"

   ReDim sRyoiki(3)
   sRyoiki(1) = "生産"
   sRyoiki(2) = "購買・販売"
   sRyoiki(3) = "原価・業績"

   ReDim sTitle(3)
   sTitle(1) = "スロット"
   sTitle(2) = "領域"
   sTitle(3) = "アドオン"

   ReDim sAddon(1)
   sAddon(1) = "*_*"

   ReDim sKinou(1)
   sKinou(1) = "機能設計"

   ReDim sBefore(7)
   sBefore(1) = "要件部"
   sBefore(2) = "仕様部"
   sBefore(3) = "機能設計レビュー"
   sBefore(4) = "クライアントサインオフ"
   sBefore(5) = "機能設計トランジション"
   sBefore(6) = "技術設計・構築"
   sBefore(7) = "受入テスト"

   ReDim sAfter(7)
   sAfter(1) = "01 要件部"
   sAfter(2) = "02 仕様部"
   sAfter(3) = "03 機能設計レビュー"
   sAfter(4) = "04 クライアントサインオフ"
   sAfter(5) = "05 機能設計トランジション"
   sAfter(6) = "06 技術設計・構築"
   sAfter(7) = "07 受入テスト"

   '画面更新OFF
   Application.ScreenUpdating = False

   '列の挿入とeofの入力
   Call WriteTitle(sSheet, sTitle)

   '全体をコピーして値のみ貼り付け
   Call PasteSpecial(sSheet)

   '文字列を置換
   Call ReplaceRepeat(sSheet, sRange, sBefore, sAfter, 7)

   'スロットを探してコピー
   Call FindCopyCells(sSheet, sRange, sSlot, 4, 3)

   'コピーを繰り返す
   Call CopyRepeat(2, 2)

   'スロットを探して削除
   Call DeleteRow(sSheet, sRange, sSlot, 4)

   '領域を探してコピー
   Call FindCopyCells(sSheet, sRange, sRyoiki, 3, 2)

   'コピーを繰り返す
   Call CopyRepeat(2, 3)

   '領域を探して削除
   Call DeleteRow(sSheet, sRange, sRyoiki, 3)

   'アドオン("_"の入っている項目)を探してコピー
   Call FindCopyCells(sSheet, sRange, sAddon, 1, 1)

   'コピーを繰り返す
   Call CopyRepeat(2, 4)

   'アドオン("_"の入っている項目)を探して削除
   Call DeleteRow(sSheet, sRange, sAddon, 1)

   '"機能設計"を探して削除
   Call DeleteRow(sSheet, sRange, sKinou, 1)

   'コピーや切取りの操作を解除
   Application.CutCopyMode = False

   '画面更新ON
   Application.ScreenUpdating = True

End Sub

'No.1 「sFind()」で指定した文字列を「sSh」シートの「sRa」の範囲から検索し、
'「lDiff」列だけ左にずらしてコピーすることを「lEnsNum」回(配列の次元)だけ繰り返す
Sub FindCopyCells(sSh As String, sRa As String, sFind() As String, lEndNum As Long, lDiff As Long)

   Dim lRow As Long
   Dim lCol As Long
   Dim lNum As Long
   Dim sAddress As String
   Dim c As Object

   '以前に実行したコピーや切取りの操作を無効にする
   Application.CutCopyMode = False

   For lNum = 1 To lEndNum
      '対象のワークシートおよび範囲を指定
      With Worksheets(sSh).Range(sRa)
         '上記のワークシート内でsFind()を検索しオブジェクトを取得する
         Set c = .Find(What:=sFind(lNum), LookIn:=xlValues, lookat:=xlWhole, _
                     SearchOrder:=xlByColumns, MatchByte:=False)

         '取得したオブジェクトをコピーして、指定したセルに値だけ貼りつける
         If Not c Is Nothing Then
            sAddress = c.Address
            Do
               lRow = c.row
               lCol = c.Column
               c.Copy

               '値だけ貼りつけるオプションつき
               Cells(lRow, lCol - lDiff).PasteSpecial Paste:=xlPasteValues

               '検索を継続する(次の検索)
               Set c = .FindNext(c)

               '最初に検索したセルに到達するまで繰り返す
               If c.Address = sAddress Then Exit Do
            Loop
         End If

         Set c = Nothing
      End With
   Next lNum

   '以前に実行したコピーや切取りの操作を無効にする
   Application.CutCopyMode = False

End Sub

'No.2 指定したセル(lRw,lCo)Aから、次に空白以外が入力されたセルBを探し、
'AとBの間にあるセルに、Aの値を貼りつける
'Bから次の空白以外が入力されたセルCを探し、同じように貼りつける
'eofが入力されたセルに到達すると終了する
Sub CopyRepeat(lRw As Long, lCo As Long)

   Dim lEndRow As Long

   '以前に実行したコピーや切取りの操作を無効にする
   Application.CutCopyMode = False

   '次の空欄前の行を取得(CTRL+↓)
   lEndRow = Cells(lRw, lCo).End(xlDown).row

   While Cells(lEndRow, lCo).Value <> "eof"
      '次の空白以外の入力された行を取得(CTRL+↓)
      lEndRow = Cells(lRw, lCo).End(xlDown).row

      '基点となったセルの値をコピーする
      Cells(lRw, lCo).Copy

      '基点となったセルから、上記で取得したセルの間までに値を貼りつける
      Range(Cells(lRw, lCo), Cells(lEndRow - 1, lCo)).PasteSpecial Paste:=xlPasteValues

      '上記で取得したセルに移動する
      Cells(lEndRow, lCo).Select

      'セル情報取得
      lRw = Cells(lEndRow, lCo).row
      lCo = Cells(lEndRow, lCo).Column
   Wend

   '以前に実行したコピーや切取りの操作を無効にする
   Application.CutCopyMode = False

End Sub

'No.3 「sFind()」で指定した文字列を「sSh」シートの「sRa」の範囲から探し、その行を削除する
Sub DeleteRow(sSh As String, sRa As String, sDel() As String, lEndNum As Long)

   Dim lRow As Long
   Dim lCol As Long
   Dim lNum As Long
   Dim c As Object

   '以前に実行したコピーや切取りの操作を無効にする
   Application.CutCopyMode = False

   For lNum = 1 To lEndNum
      '対象のワークシートおよび範囲を指定
      With Worksheets(sSh).Range(sRa)
         '上記のワークシート内でsFind()を検索しオブジェクトを取得する
         Set c = .Find(What:=sDel(lNum), LookIn:=xlValues, lookat:=xlWhole, _
                     SearchOrder:=xlByColumns, MatchByte:=False)

         '取得したオブジェクトの行を削除し、次の検索を実行し、同様に削除する
         If Not c Is Nothing Then
            Do
               lRow = c.row
               Rows(lRow).Delete

               '検索を繰り返す
               Set c = Worksheets(sSh).Range(sRa).Find(What:=sDel(lNum), LookIn:=xlValues, lookat:=xlWhole, _
                                             SearchOrder:=xlByColumns, MatchByte:=False)

            '対象のオブジェクトが見つからなくなるまで続ける
            Loop While Not c Is Nothing
         End If

         Set c = Nothing
      End With
   Next lNum

   '以前に実行したコピーや切取りの操作を無効にする
   Application.CutCopyMode = False

End Sub

'2列目から3列挿入し、1行目に項目を入力して、最終行の下に「eof」を入力する
Sub WriteTitle(sSh As String, sVal() As String)

   Dim lEndRow As Long
   Dim lEndCol As Long
   Dim lNum As Long

   '「sSh」シートをアクティブにする
   Worksheets(sSh).Activate

   '2列目から3列挿入する
   Worksheets(sSh).Range(Columns(2), Columns(4)).Insert

   '1行目に項目を入力する
   Worksheets(sSh).Cells(1, 2).Value = sVal(1)
   Worksheets(sSh).Cells(1, 3).Value = sVal(2)
   Worksheets(sSh).Cells(1, 4).Value = sVal(3)

   '基点となるセル(原点)を選択する
   Worksheets(sSh).Cells(1, 1).Select

   '次の空白行の手前まで下にとぶ
   lEndRow = Worksheets(sSh).Cells(1, 1).End(xlDown).row

   '次の空白列の手前まで右に飛ぶ
   lEndCol = Worksheets(sSh).Cells(1, 1).End(xlToRight).Column

   '最終行の下に「eof」を入力する
   For lNum = 1 To lEndCol
      Worksheets(sSh).Cells(lEndRow + 1, lNum) = "eof"
   Next lNum

End Sub

'置換前後の文字列を渡し、指定したシートの範囲内で、対象文字列がなくなるまで置換を繰り返す
Sub ReplaceRepeat(sSh As String, sRa As String, sBe() As String, sAf() As String, _
               lRep As Long)

   Dim c As Object
   Dim lNum As Long

   '以前に実行したコピーや切取りの操作を無効にする
   Application.CutCopyMode = False

   For lNum = 1 To lRep
      '対象のワークシートおよび範囲を指定
      With Worksheets(sSh).Range(sRa)

         '上記のワークシート内でsFind()を検索しオブジェクトを取得する
         Set c = .Find(What:=sBe(lNum), LookIn:=xlValues, lookat:=xlWhole, _
                     SearchOrder:=xlByColumns, MatchByte:=False)

         '検索語句が存在する場合には、文字列置換を実行
         If Not c Is Nothing Then
            Do
               '上記のワークシートおよび範囲内で文字列を置換する
               .Replace What:=sBe(lNum), Replacement:=sAf(lNum), _
                           SearchOrder:=xlByColumns, MatchByte:=False

               '検索を続行
               Set c = .FindNext(c)

            '検索語句が存在する間、置換を繰り返す
            Loop While Not c Is Nothing
         End If

         'オブジェクトを開放
         Set c = Nothing
      End With
   Next lNum

End Sub

'値のある範囲を指定し、同じ場所に値のみコピーする
Sub PasteSpecial(sSh As String)

   Dim lEndRow As Long
   Dim lEndCol As Long
   Dim lNum As Long

   '「sSh」シートをアクティブにする
   Worksheets(sSh).Activate

   '基点となるセル(原点)を選択する
   Worksheets(sSh).Cells(1, 1).Select

   '次の空白行の手前まで下にとぶ
   lEndRow = Worksheets(sSh).Cells(1, 1).End(xlDown).row

   '次の空白列の手前まで右に飛ぶ
   lEndCol = Worksheets(sSh).Cells(1, 1).End(xlToRight).Column

   '値のある範囲をコピー
   Worksheets(sSh).Range(Cells(1, 1), Cells(lEndRow, lEndCol)).Copy

   'コピーした範囲を値のみ貼り付け
   Worksheets(sSh).Range(Cells(1, 1), Cells(lEndRow, lEndCol)).PasteSpecial Paste:=xlPasteValues

   '以前に実行したコピーや切取りの操作を無効にする
   Application.CutCopyMode = False

End Sub

'シート間の範囲内のコピー
Sub Sheet2Sheet(sShFr As String, sShTo As String)

   Dim lEndRow As Long
   Dim lEndCol As Long
   Dim lNum As Long

   'コピー先のシートをタイトル行を除いて空にする
   Worksheets(sShTo).Rows("2:65536").Delete

   '「sShFr」シートをアクティブにする
   Worksheets(sShFr).Activate

   '基点となるセル(原点)を選択する
   Worksheets(sShFr).Cells(1, 1).Select

   '次の空白行の手前まで下にとぶ
   lEndRow = Worksheets(sShFr).Cells(1, 1).End(xlDown).row

   '次の空白列の手前まで右に飛ぶ
   lEndCol = Worksheets(sShFr).Cells(1, 1).End(xlToRight).Column

   '値のある範囲をコピー
   Worksheets(sShFr).Range(Cells(2, 1), Cells(lEndRow - 1, lEndCol)).Copy

   '「sShTo」シートをアクティブにする
   Worksheets(sShTo).Activate

   'コピーした範囲を貼り付け
   Worksheets(sShTo).Range(Cells(2, 1), Cells(lEndRow - 1, lEndCol)).PasteSpecial

   '以前に実行したコピーや切取りの操作を無効にする
   Application.CutCopyMode = False

End Sub

'指定したシートの1行目から指定した文字列を検索し、該当列の行数を調べ、
'該当列の最終行のセルの行と列の値を返す
Function DefineRange(sSh As String, sFind As String) As Long()

   Dim lRange() As Long
   Dim lRo As Long
   Dim lCo As Long

   ReDim lRange(2)

   '対象のワークシートおよび1行目を指定
   With Worksheets(sSh).Range("A1:IV1")
      '上記のワークシート内でsFindを検索しオブジェクトを取得する
      Set c = .Find(What:=sFind, LookIn:=xlValues, lookat:=xlWhole, _
                  SearchOrder:=xlByColumns, MatchByte:=False)

      lRo = c.row
      lCo = c.Column

      Set c = Nothing

      '基点となるセルを選択する
      Cells(1, lCo).Select

      '次の空白行の手前まで下にとぶ
      lRo = Cells(1, lCo).End(xlDown).row

   End With

   lRange(1) = lRo
   lRange(2) = lCo

 DefineRange = lRange

End Function
ホーム
inserted by FC2 system