- ベストアンサー
エクセル関数・VBAで行の挿入方法を考える
- エクセルのシートで、発生月ごとのXとYの数値帯を比較し、行の挿入を自動化する方法を考えます。
- 関数とVBAを組み合わせて、最小値と最大値を比較し、不足する行数を算出し、行位置を特定して行を追加します。
- 発生月と数値帯が昇順に並んでいる条件下で、異なる数値帯への対応も可能です。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
#1です。 挿入した行に値を設定するモジュールを追加しました。 エラーに関しては状況がわかりませんので対応していません。 またいろいろなパターンではテストしていないので 頑張って改良してください。 --- Sub mSample() Dim i As Long Dim strYM As String Dim xmx As Long '同一年月のXの最大数値 Dim xmi As Long '同一年月のXの最小数値 Dim ymx As Long '同一年月のYの最大数値 Dim ymi As Long '同一年月のYの最小数値 Dim xed As Long '同一年月のXの最終行 Dim yed As Long '同一年月のYの最終行 '1行目はタイトル欄とする '最終行を取得 i = Range("A65536").End(xlUp).Row Do While i > 1 xmx = 0 xmi = 0 ymx = 0 xmi = 0 yed = i strYM = Cells(i, 1).Value Do While Cells(i, 1).Value = strYM And i > 1 If Cells(i, 2).Value = "Y" Then If ymx = 0 Then 'Yの最大数値を取得 ymx = Cells(i, 3).Value End If Else If xmx = 0 Then xed = i 'Yの最小数値を取得 ymi = Cells(i + 1, 3).Value 'Xの最大数値を取得 xmx = Cells(i, 3).Value End If End If i = i - 1 Loop 'Xの最小数値を取得 xmi = Cells(i + 1, 3).Value 'Xの最大数値が大きいときYの最終行の下に行を挿入 If xmx > ymx Then Rows(CStr(yed + 1) & ":" & CStr(yed + (xmx - ymx) / 500)).Insert Shift:=xlDown Call mSet(strYM, "Y", ymx, (xmx - ymx) / 500, 1, yed + 1) End If 'Yの最小数値が大きいときYの開始行の上に行を挿入 If ymi > xmi Then Rows(CStr(xed + 1) & ":" & CStr(xed + (ymi - xmi) / 500)).Insert Shift:=xlDown Call mSet(strYM, "Y", ymi, (ymi - xmi) / 500, -1, xed + (ymi - xmi) / 500) End If 'Yの最大数値が大きいときXの最終行の下に行を挿入 If xmx < ymx Then Rows(CStr(xed + 1) & ":" & CStr(xed + (ymx - xmx) / 500)).Insert Shift:=xlDown Call mSet(strYM, "X", xmx, (ymx - xmx) / 500, 1, xed + 1) End If 'Xの最小数値が大きいときXの開始行の上に行を挿入 If ymi < xmi Then Rows(CStr(i + 1) & ":" & CStr(i + (xmi - ymi) / 500)).Insert Shift:=xlDown Call mSet(strYM, "X", xmi, (xmi - ymi) / 500, -1, i + (xmi - ymi) / 500) End If Loop End Sub '引数 '発生年月、種、開始数値帯、範囲、増減、開始行 Sub mSet(strYM As String, strSu As String, lngS As Long, lngH As Long, lngD As Long, lngR As Long) Dim i As Long Dim s As Long Dim e As Long Dim w As Long w = lngS '開始行、終了行を設定 If lngD > 0 Then s = lngR e = lngR + lngH - 1 Else s = lngR e = lngR - lngH + 1 End If 'セルにデータを設定 For i = s To e Step lngD Cells(i, 1).Value = strYM Cells(i, 2).Value = strSu w = w + 500 * lngD Cells(i, 3).Value = w Next i End Sub
その他の回答 (1)
- o_chi_chi
- ベストアンサー率45% (131/287)
ご希望通りかどうか分かりませんが。。。。 --- Sub mSample() Dim i As Long Dim strYM As String Dim xmx As Long '同一年月のXの最大数値 Dim xmi As Long '同一年月のXの最小数値 Dim ymx As Long '同一年月のYの最大数値 Dim ymi As Long '同一年月のYの最小数値 Dim xed As Long '同一年月のXの最終行 Dim yed As Long '同一年月のYの最終行 '1行目はタイトル欄とする '最終行を取得 i = Range("A65536").End(xlUp).Row Do While i > 1 '初期化 xmx = 0 xmi = 0 ymx = 0 xmi = 0 yed = i strYM = Cells(i, 1).Value '発生月が同じ間 Do While Cells(i, 1).Value = strYM And i > 1 If Cells(i, 2).Value = "Y" Then If ymx = 0 Then 'Yの最大数値を取得 ymx = Cells(i, 3).Value End If Else If xmx = 0 Then xed = i 'Yの最小数値を取得 ymi = Cells(i + 1, 3).Value 'Xの最大数値を取得 xmx = Cells(i, 3).Value End If End If i = i - 1 Loop 'Xの最小数値を取得 xmi = Cells(i + 1, 3).Value 'Xの最大数値が大きいときYの最終行の下に行を挿入 If xmx > ymx Then Rows(CStr(yed + 1) & ":" & CStr(yed + (xmx - ymx) / 500)).Insert Shift:=xlDown End If 'Yの最小数値が大きいときYの開始行の上に行を挿入 If ymi > xmi Then Rows(CStr(xed + 1) & ":" & CStr(xed + (ymi - xmi) / 500)).Insert Shift:=xlDown End If 'Yの最大数値が大きいときXの最終行の下に行を挿入 If xmx < ymx Then Rows(CStr(xed + 1) & ":" & CStr(xed + (ymx - xmx) / 500)).Insert Shift:=xlDown End If 'Xの最小数値が大きいときXの開始行の上に行を挿入 If ymi < xmi Then Rows(CStr(i + 1) & ":" & CStr(i + (xmi - ymi) / 500)).Insert Shift:=xlDown End If Loop End Sub
お礼
ご回答ありがとうございます。素晴らしいです。試してみます。
補足
試してみたところ、シート上では上手く完了したようですが、下の箇所でデバックとなります。 'Xの最大数値を取得 xmx = Cells(i, 3).Value 行挿入も実行されているのに、何故でしょう? また、説明不足で申し訳ございませんが、追加された行に、発生月・種・数値帯 の値を入れるためにはどうすれば良いのでしょうか? 発生月と種は、追加の対象となったものと同じ値、数値帯は対象となったところ から、500刻みで追加された分だけ・・・ 度々、お手数おかけしますが、教えてください。
お礼
ありがとうございます。シートの結果自体は上手くいきました。 デバック発生箇所については調べてみます。