Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


1673 / 13646 ツリー ←次へ | 前へ→

【72700】コードを短くしたい マリモ 12/9/7(金) 13:00 質問[未読]
【72702】Re:コードを短くしたい UO3 12/9/7(金) 16:07 発言[未読]
【72703】Re:コードを短くしたい Yuki 12/9/7(金) 16:09 発言[未読]
【72704】Re:コードを短くしたい Yuki 12/9/7(金) 16:14 発言[未読]
【72705】Re:コードを短くしたい UO3 12/9/7(金) 16:21 発言[未読]
【72706】Re:コードを短くしたい UO3 12/9/7(金) 16:55 発言[未読]
【72707】Re:コードを短くしたい UO3 12/9/7(金) 17:17 発言[未読]
【72718】Re:コードを短くしたい UO3 12/9/7(金) 21:48 発言[未読]
【72728】Re:コードを短くしたい マリモ 12/9/10(月) 10:42 お礼[未読]

【72700】コードを短くしたい
質問  マリモ  - 12/9/7(金) 13:00 -

引用なし
パスワード
   U03さんに2箇所教えていただいたものに
マクロの記録を使ったものを加えてあります。
動作としては一応動作しておりますが、
削除しても構わないところや、コンパクトにまとめれるところがあれば
教えていただきたいです。

Sub sample1()
  Range("C:C,DU:DV").Select
  Selection.Delete Shift:=xlToLeft
  Rows("1:2").Select
  Selection.Delete Shift:=xlUp
  Cells.Select
  Selection.Replace What:=" ", Replacement:="", LookAt:=xlPart, _
    SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
    ReplaceFormat:=False
  Selection.Replace What:="男", Replacement:="m", LookAt:=xlPart, _
    SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
    ReplaceFormat:=False
  Selection.Replace What:="女", Replacement:="f", LookAt:=xlPart, _
    SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
    ReplaceFormat:=False
  Dim r As Range
  Dim i As Long
  Dim z As Long
  With ActiveSheet.UsedRange
    z = .Cells(.Cells.Count).Row
  End With
  For i = 3 To z Step 4
    If r Is Nothing Then
      Set r = Rows(i).Resize(2)
    Else
      Set r = Union(r, Rows(i).Resize(2))
    End If
  Next
  If Not r Is Nothing Then r.EntireRow.Delete
   Rows("1:1").Select
  Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
  Range("C1").Select
  ActiveCell.FormulaR1C1 = "0"
  Range("D1").Select
  ActiveCell.FormulaR1C1 = "1"
  Range("C1:D1").Select
  Selection.AutoFill Destination:=Range("C1:DS1"), Type:=xlFillDefault
  Range("C1:DS1").Select
  Dim x As Long
  Dim y As Long
  Dim j As Long
  Dim k As Long
  Dim aCode As String
  Dim aName As String
  Dim mf As String
  Dim w() As Variant
  With Sheets("Sheet1")
    y = .Range("A" & .Rows.Count).End(xlUp).Row
    x = .Cells(1, .Columns.Count).End(xlToLeft).Column
    ReDim w(1 To .Rows.Count, 1 To 5)
    For i = 2 To y Step 2
      aCode = .Cells(i, "A").Value
      aName = .Cells(i + 1, "A").Value
      For z = i To i + 1
        mf = .Cells(z, "B").Value
        For j = 3 To x
          k = k + 1
          w(k, 1) = aCode
          w(k, 2) = aName
          w(k, 3) = mf
          w(k, 4) = .Cells(1, j).Value
          w(k, 5) = .Cells(z, j).Value
        Next
      Next
    Next
  End With
  With Sheets("Sheet2")
    .Cells.ClearContents
    .Range("A1").Resize(k, UBound(w, 2)).Value = w
    .Select
  End With
  Rows("1:1").Select
  Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
  Range("A1").Select
  ActiveCell.FormulaR1C1 = "code"
  Range("B1").Select
  ActiveCell.FormulaR1C1 = "cyomei"
  Range("C1").Select
  ActiveCell.FormulaR1C1 = "sex"
  Range("D1").Select
  ActiveCell.FormulaR1C1 = "age"
  Range("E1").Select
  ActiveCell.FormulaR1C1 = "pop"
  Range("F1").Select
  MsgBox "完了!"
End Sub

【72702】Re:コードを短くしたい
発言  UO3  - 12/9/7(金) 16:07 -

引用なし
パスワード
   ▼マリモ さん:

こんにちは

まず、以下のパターンの簡素化をはかってみてください。

  Range("C:C,DU:DV").Select
  Selection.Delete Shift:=xlToLeft

     ↓

  Range("C:C,DU:DV").Delete Shift:=xlToLeft

なんとか.Select
Selection.何何

これを、何とか.何何 と1行にします。

  Range("C1").Select
  ActiveCell.FormulaR1C1 = "0"

     ↓

  Range("C1").Value = "0"

マクロ記録しますと、FormulaR1C1に対して入力した固定値がセットされますが
Valueのほうがわかりやすいですね。

それと、 Dim での変数定義は、プロシジャの先頭にまとめたほうが
後々見やすいですね。

いずれにしても、まず、上記の簡素化を行い、さらに必要なら、その先を考えましょう。

【72703】Re:コードを短くしたい
発言  Yuki  - 12/9/7(金) 16:09 -

引用なし
パスワード
   ▼マリモ さん:
Selectを無くして見ました
検証はしていませんのでエラーがあるかもしれません。

Sub sample2()
  Dim r As Range
  Dim i As Long
  Dim z As Long
  
  Dim x As Long
  Dim y As Long
  Dim j As Long
  Dim k As Long
  Dim aCode As String
  Dim aName As String
  Dim mf As String
  Dim w() As Variant
  Dim v  As Variant
  
  With Worksheets("Sheet3")  ' 最初に処理するシート名
    .Range("C:C,DU:DV").Delete Shift:=xlToLeft
    .Rows("1:2").Delete Shift:=xlUp
    With .UsedRange
      .Replace What:=" ", Replacement:="", LookAt:=xlPart, _
        SearchOrder:=xlByRows, MatchCase:=False, _
        SearchFormat:=False, ReplaceFormat:=False
      .Replace What:="男", Replacement:="m", LookAt:=xlPart, _
        SearchOrder:=xlByRows, MatchCase:=False, _
        SearchFormat:=False, ReplaceFormat:=False
      .Replace What:="女", Replacement:="f", LookAt:=xlPart, _
        SearchOrder:=xlByRows, MatchCase:=False, _
        SearchFormat:=False, ReplaceFormat:=False
      z = .Cells(.Cells.Count).Row
    End With
    For i = 3 To z Step 2
      If r Is Nothing Then
        Set r = Rows(i).Resize(2)
      Else
        Set r = Union(r, Rows(i).Resize(2))
      End If
    Next
    If Not r Is Nothing Then r.EntireRow.Delete
    .Rows(1).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
    .Range("C1").Value = "0"
    .Range("D1").Value = "1"
    .Range("C1:D1").AutoFill Destination:=Range("C1:DS1"), Type:=xlFillDefault
  End With
  
  With Sheets("Sheet1")
    v = .Range("A1").CurrentRegion.Value
    y = UBound(v)
    x = UBound(v, 2)
    ReDim w(1 To y, 1 To 5)
    For i = 2 To y Step 2
      aCode = v(i, 1)
      aName = v(i + 1, 1)
      For z = i To i + 1
        mf = v(z, 2)
        For j = 3 To x
          k = k + 1
          w(k, 1) = aCode
          w(k, 2) = aName
          w(k, 3) = mf
          w(k, 4) = v(1, j)
          w(k, 5) = v(z, j)
        Next
      Next
    Next
  End With
  With Sheets("Sheet2")
    .Cells.ClearContents
    .Range("A1").Resize(k, UBound(w, 2)).Value = w
    .Rows(1).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
    .Range("A1").Value = "code"
    .Range("B1").Value = "cyomei"
    .Range("C1").Value = "sex"
    .Range("D1").Value = "age"
    .Range("E1").Value = "pop"
    MsgBox "完了!"
  End With
End Sub

【72704】Re:コードを短くしたい
発言  Yuki  - 12/9/7(金) 16:14 -

引用なし
パスワード
   ▼マリモ さん:
>    For i = 3 To z Step 2
>      If r Is Nothing Then
>        Set r = Rows(i).Resize(2)
>      Else
>        Set r = Union(r, Rows(i).Resize(2))
>      End If
>    Next
>    If Not r Is Nothing Then r.EntireRow.Delete
>    .Rows(1).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
>    .Range("C1").Value = "0"
>    .Range("D1").Value = "1"
>    .Range("C1:D1").AutoFill Destination:=Range("C1:DS1"), Type:=xlFillDefault
>  End With
上記で Rows と Range の参照設定 (.Rows or .Range) が抜けていました。

【72705】Re:コードを短くしたい
発言  UO3  - 12/9/7(金) 16:21 -

引用なし
パスワード
   ▼マリモ さん:

▼マリモ さん:

追伸です。

マクロ記録でできあがる、不要な動きのコードは不要ですね。
たとえば
Range("C1:DS1").Select
(意味があれば別ですが)

それと、
最初のブロック、処理対象のシートはどれですか?
アップされたコードでは、どのシートということは特定されず
たまたま、実行時点でアクティブになっていたシートに対して処理されます。

また、最後のブロックですが、処理対象のシートはSheet1ですか?Sheet2ですか?
アップされたコード構成では、SHeet2に対して処理されてますね。

【72706】Re:コードを短くしたい
発言  UO3  - 12/9/7(金) 16:55 -

引用なし
パスワード
   ▼マリモ さん:

以下のような簡素化もできます。

  Range("C1").Select
  ActiveCell.FormulaR1C1 = "0"
  Range("D1").Select
  ActiveCell.FormulaR1C1 = "1"
  Range("C1:D1").Select
  Selection.AutoFill Destination:=Range("C1:DS1"), Type:=xlFillDefault

    ↓

  Range("C1").Value = 0
  Range("D1").Value = 1
  Range("C1:D1").AutoFill Destination:=Range("C1:DS1"), Type:=xlFillDefault

    ↓

  Range("C1") = 0
  Range("C1").Resize(, 121).DataSeries


  Range("A1").Select
  ActiveCell.FormulaR1C1 = "code"
  Range("B1").Select
  ActiveCell.FormulaR1C1 = "cyomei"
  Range("C1").Select
  ActiveCell.FormulaR1C1 = "sex"
  Range("D1").Select
  ActiveCell.FormulaR1C1 = "age"
  Range("E1").Select
  ActiveCell.FormulaR1C1 = "pop"

   ↓

  Range("A1").Value = "code"
  Range("B1").Value = "cyomei"
  Range("C1").Value = "sex"
  Range("D1").Value = "age"
  Range("E1").Value = "pop"

   ↓

  Range("A1:E1").Value = Array("code", "cyomei", "sex", "age", "pop")

また、簡素化といえるかどうか、実際のコード実行数はかわらないというか、むしろ増えますが
変換数が今回のような3種類ではなく、多い場合には有効かも。

  Cells.Select
  Selection.Replace What:=" ", Replacement:="", LookAt:=xlPart, _
    SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
    ReplaceFormat:=False
  Selection.Replace What:="男", Replacement:="m", LookAt:=xlPart, _
    SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
    ReplaceFormat:=False
  Selection.Replace What:="女", Replacement:="f", LookAt:=xlPart, _
    SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
    ReplaceFormat:=False

   ↓

まず、変数定義

  Dim aryCvt1 As Variant
  Dim aryCvt2 As Variant
  Dim idx As Long

で、実行コードを
  
  aryCvt1 = arrat(" ", "男", , "女")
  aryCvt2 = arrat("", "m", "f")
  
  For idx = LBound(aryCvt1) To UBound(aryCvt1)
    Cells.Replace What:=aryct1(idx), Replacement:=aryct2(idx), LookAt:=xlPart, _
      SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
      ReplaceFormat:=False
  Next

【72707】Re:コードを短くしたい
発言  UO3  - 12/9/7(金) 17:17 -

引用なし
パスワード
  
Range("C1").Resize(, 121).DataSeries
これは
Range("C1:DS1").DataSeries
こちらのほうが、わかりやすかったですね。

【72718】Re:コードを短くしたい
発言  UO3  - 12/9/7(金) 21:48 -

引用なし
パスワード
   タイプミスがありました。

  aryCvt1 = arrat(" ", "男", , "女")
  aryCvt2 = arrat("", "m", "f")

これは

  aryCvt1 = array(" ", "男", , "女")
  aryCvt2 = array("", "m", "f")

です。

【72728】Re:コードを短くしたい
お礼  マリモ  - 12/9/10(月) 10:42 -

引用なし
パスワード
   お返事が遅くなり、すみません。
最初にこのページを開いたとき、沢山の書き込みがあって
胸が熱くなりました。
UO3さん、Yukiさん、ありがとうございます。
色々と取り入れて動作確認いたしました。

Sub sample1()
  
  Dim r As Range
  Dim i As Long
  Dim z As Long
  
  Dim aryCvt1 As Variant
  Dim aryCvt2 As Variant
  Dim idx As Long

  Dim x As Long
  Dim y As Long
  Dim j As Long
  Dim k As Long
  Dim aCode As String
  Dim aName As String
  Dim mf As String
  Dim w() As Variant

  With Sheets("Sheet1")
  Range("C:C,DU:DV").Delete Shift:=xlToLeft
  Rows("1:2").Delete Shift:=xlUp
  aryCvt1 = Array(" ", "男", "女")
  aryCvt2 = Array("", "m", "f")
 
  For idx = LBound(aryCvt1) To UBound(aryCvt1)
    Cells.Replace What:=aryCvt1(idx), Replacement:=aryCvt2(idx), LookAt:=xlPart, _
      SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
      ReplaceFormat:=False
  Next

  With ActiveSheet.UsedRange
    z = .Cells(.Cells.Count).Row
  End With
 
  For i = 3 To z Step 4
    If r Is Nothing Then
      Set r = Rows(i).Resize(2)
    Else
      Set r = Union(r, Rows(i).Resize(2))
    End If
  Next
  End With

  If Not r Is Nothing Then r.EntireRow.Delete
  Rows("1:1").Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove

  Range("C1") = 0
  Range("C1:DS1").DataSeries

  With Sheets("Sheet1")
 
    y = .Range("A" & .Rows.Count).End(xlUp).Row
    x = .Cells(1, .Columns.Count).End(xlToLeft).Column
    ReDim w(1 To .Rows.Count, 1 To 5)

    For i = 2 To y Step 2
      aCode = .Cells(i, "A").Value
      aName = .Cells(i + 1, "A").Value
      For z = i To i + 1
        mf = .Cells(z, "B").Value
        For j = 3 To x
          k = k + 1
          w(k, 1) = aCode
          w(k, 2) = aName
          w(k, 3) = mf
          w(k, 4) = .Cells(1, j).Value
          w(k, 5) = .Cells(z, j).Value
        Next
      Next
    Next
  End With
 
  With Sheets("Sheet2")
    .Cells.ClearContents
    .Range("A1").Resize(k, UBound(w, 2)).Value = w
    .Select
  End With
  
  With Sheets("Sheet2")
  Rows("1:1").Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
  Range("A1:E1").Value = Array("code", "cyomei", "sex", "age", "pop")
  MsgBox "完了!"
  End With
 
End Sub

1673 / 13646 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free