エクセル関数・VBAで行の挿入方法を考える

このQ&Aのポイント
  • エクセルのシートで、発生月ごとのXとYの数値帯を比較し、行の挿入を自動化する方法を考えます。
  • 関数とVBAを組み合わせて、最小値と最大値を比較し、不足する行数を算出し、行位置を特定して行を追加します。
  • 発生月と数値帯が昇順に並んでいる条件下で、異なる数値帯への対応も可能です。
回答を見る
  • ベストアンサー

エクセル 関数・VBA 行位置・行数・行挿入

下のようなシートがあり、自動で、発生月ごとのXとYの数値帯の個数を揃えるように(行挿入) 修正したいのですが、どのような方法が考えられますでしょうか?同様のシートが多数あり、 それぞれ数値帯は異なり、それらへも対応させたいのです。 発生月ごとに、XとYの数値帯を比較して、少ない方へ行を追加すれば良いかと思い、関数とVBA の組合せで何とかならないかと考えたのですが、進みません。 例えば、関数で、発生月ごとのXとYについて、最小値と最大値をそれぞれ比較して、500で割っ て、足りない行数を算出し、また、それぞれの最小値と最大値のある行位置を特定して、それら を変数として、VBAで実行させる・・・ 最小値と最大値はDMAX(DMIN)で算出できたのですが、数値帯が小さい方へ不足することもあれ ば、大きい方へ不足することもありますし、差が無い場合もありますし、さらには、行位置の特 定もどうすれば良いか思いつきません。 そもそも、この考え方が不適切なのでしょうか? お手数ですが、教えてください。 A列に発生月を示す6桁半角数字(例/200512) B列に種を示す1半角英字(XまたはY) C列に数値帯を示す500刻みの4または5桁半角数字(例/8000、32500) ※発生月と数値帯は昇順に並んでいます。   A    B   C  発生月  種  数値帯  200512  X   9500  200512  X   10000  200512  X   10500  ・  ・  200512  Y   8000  200512  Y   8500  200512  Y   9000  ・  ・  200601  X   10500  200601  X   11000  ・  ・  200601  Y   10500  200601  Y   11000  ・  ・

質問者が選んだベストアンサー

  • ベストアンサー
  • o_chi_chi
  • ベストアンサー率45% (131/287)
回答No.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

nonboo
質問者

お礼

ありがとうございます。シートの結果自体は上手くいきました。 デバック発生箇所については調べてみます。

その他の回答 (1)

  • o_chi_chi
  • ベストアンサー率45% (131/287)
回答No.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 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

nonboo
質問者

お礼

ご回答ありがとうございます。素晴らしいです。試してみます。

nonboo
質問者

補足

試してみたところ、シート上では上手く完了したようですが、下の箇所でデバックとなります。 'Xの最大数値を取得 xmx = Cells(i, 3).Value 行挿入も実行されているのに、何故でしょう? また、説明不足で申し訳ございませんが、追加された行に、発生月・種・数値帯 の値を入れるためにはどうすれば良いのでしょうか? 発生月と種は、追加の対象となったものと同じ値、数値帯は対象となったところ から、500刻みで追加された分だけ・・・ 度々、お手数おかけしますが、教えてください。

関連するQ&A

  • VBAか関数 「 2と3の組合せ 」 の行が、いくつあるか?

    VBAか関数 「 2と3の組合せ 」 の行が、いくつあるか? Windows XP Home Edition SP3 Office XP Personal 2002 Excel 2002 画像の 「 C列 D列 E列 」 の 「 3列 」 だけを使った質問でございます。 数値は 2桁の整数 までしかありません。 6行目の「 C列 D列 E列 」以外で、オートフィルタをかけた後ですが、空白行もたまにございます。 オートフィルタをかけた後ですので、データのある最後行以下は全部空白です。   実際には、セルには色分けはされておりません。 ---質問のまとめ-------------------------------------- ● 「 2 と 3 の組合せ 」(画像の黄色セル) の行が、いくつあるか? を算出できる、関数 か マクロは、ありますでしょうか? 質問の例では、答えは 「 3行 」 となります。 存在しない場合には、「 0行 」 となります。 ----------------------------------------------------- また、 「 1 と 3 の組合せ 」 の行が、いくつあるか? 「 * と * の組合せ 」 の行が、いくつあるか? などのように、いろいろと算出できればと思っております。 非常にややこしい質問で、恐れ入ります。 今までは、手作業で、6行目にオートフィルタをかけて行っておりました。 何卒、ご教示のほどをお願い致します。 

  • 【Excel VBA】指定した行の最大値を持つセル番地を取得したい

    指定した範囲内で最大値及び最小値のセル番地を取得するには、 どうコーディングしたらよろしいでしょうか? 対象範囲 A1:Z2000の各行(行番は変数で処理) 例えば、 ---------------------------------------------------- For x = 1 To 2000 Range(A列のx行目:A列のx行目)の最大値 → B列                最小値 → Y列 Next x ---------------------------------------------------- このように、2000行分同じことを繰り返し、それぞれの行内での 最大値及び最小値を含むセルの列名を取得し、 B列のx行目を赤(最大値) Y列のx行目を青(最小値) に着色したいのです。 よろしくお願いします。

  • VBAでの行挿入について

    Excel VBAの条件に合った場合、行挿入&挿入した行のセルに特定の値を入力 VBA初心者です。Excel2007、XPを使用しています。 A列からCK列、平均100行程度の顧客データがあります。 このデータは列数は変わりませんが、行数は毎回異なり、 1行1顧客ではなく、同じ顧客で数行で入ることがあります。 しかしA列の顧客番号で判別できるようにはなっています。 目標は下記の点です。 「BC列」に値がある場合、 1行下へ空白行を挿入(できればA~X、Z~AA、AD~CKは1行上と同じ)。 但し挿入する位置は、顧客情報の一番下(1行の場合は2行目、2行の場合は3行目と)です。 挿入した行のY列に「ポイント利用」と入力。 挿入した行のAC列に「BC列の値」を入力。 挿入した行のAB列に「1」を入力。 「BJ列」に値がある場合、 1行下へ空白行を挿入(できればA~X、Z~AA、AD~CKは1行上と同じ)。 但し挿入する位置は、顧客情報の一番下(1行の場合は2行目、2行の場合は3行目と)です。 挿入した行のY列に「送料」と入力。 挿入した行のAC列に「BJ列の値」を入力。 挿入した行のAB列に「1」を入力。 以降に必要な処理はマクロで作成できたのですが、 その後に上記項目を手作業で処理しているのも限度があるので、 最初に挿入処理できればと思ってます。 分かりづらい説明だとは思いますが、 何卒ご教授頂きたくお願い致します。

  • エクセルVBA

    A1からE20までの範囲に数字が表示されています。 そしてその表の行ごとの数値の合計をG列に算出して表示させたいのですが どのようにすれば良いのでしょうか。 VBA初心者なので、分かりやすく教えていただけると助かります。 よろしくお願いいたします。

  • エクセルの関数、VBAの使い分け

    エクセルでデータを管理しているのですが現在5つのシートで各シートが10列7000行程度データが入っていてファイルサイズが10MBを超えています。 データの行数は今後も増えていく予定で、最大行(約65000行)まで使いたいと思っているのですが、そうなるとファイルサイズが100Mぐらいになってしまいそうなのですが使用上問題はないでしょうか? 関数を多用しているのですがそれをVBAに置き換えるとファイルサイズを小さく出来るでしょうか?もし、VBAに変えた場合に使用上、関数に比べ不便が出るようなことはないでしょうか?

  • EXCELのVBAで2行を選択。

    EXCELのVBAで2行を選択するには ROW("1:2").selectでいいと思うんですが、 X行からY行まで選択にしようと思えばどうしたらいいですか? ROW("X:Y")だとエラーになって出来ないみたいです。 なんかいい方法ありますか?

  • エクセルVBAについて

    VBAに関しての質問です。 A列に日付(10行目から) B列にその日の売上が 300行(300日分)入力されてる表があるとします。 C列にその日を含めた過去N日間の最大の売上を表示させたいのです。 例えば 過去5日間なら過去5日間の最大売上げを毎日表示させたいのです 当然この場合は5日間なのでCの13行目までは空白になります。 「N」日はA1セルに任意の日数で入力することによって希望の期間の数値 が表示できるようにしたいのです。 関数を使ってできるのいですが、事情がありましてエクセルのマクロの 繰り返しのプログラムでやりたいのですが VBAに関しては全く素人ですの。どなたかご教授願えませんでしょうか よろしくお願いします。

  • エクセルの同じ行の違う列を返す関数

    エクセルの同じ行の違う列を返す関数 エクセルの関数について質問があります。 例えば、以下のようなデータがあったとして、 左からA列、B列、上から1行、2行・・・5行目に 0.1  32 0.2  9 0.3  15 0.4  2 0.5  21 といったデータがあるときに、例えば MIN(B1:B5)はB4の5とわかった場合に、 この時のA4の数値を知りたいのです。 データが膨大だとその数値をさがすだけで大変です。 よろしくお願いします。

  • エクセルのVBAで行選択

    エクセルVBAで、連続してない2行(たとえば10行目と13行目)を選択する場合 Sub test02() Dim x As Long, y As Long x = 10 y = 13 Range(x & ":" & x & "," & y & ":" & y).Select End Sub でできましたが、もっと簡単に書く方法はないでしょうか?

  • エクセル関数で条件が二つの時の数値抽出

       列方向のそれぞれ三つのセルに数値が入った78行  (75行から152行)のテーブルがあります。       今,これらと異なる列方向の三つのセルの内の左側二  つに,テーブル内の任意の行の数値をそれぞれ選択した  時,残るセルにテーブル内の残された行の数値を抽出し  たいと思いますがうまくいきません。      何方かエクセル関数で出来る方法を教えていただけま  せんか。   なお,選択行は4行だけとしており,これらを連続させず  に一行毎に設け,各行毎の抽出セルにDSUMで計算式を  作成すると数値の抽出ができますが,この方法は避けた  いと思います。     (数値選択列)(抽出列)   (テーブル)   73行 X  ,Y   ,Z      , AA  ,AB  ,AC   74行開始 終了 期間     開始 終了 期間   75行,0005 ,0011 ,0010 (空欄),0004 ,0012 ,0010   76行,0007 ,0009 ,0010 (空欄),0005 ,0011 ,0010   77行,0004 ,0011 ,0009 (空欄),0006 ,0010 ,0010 (空78行,0008 ,0003 ,0004 (空欄),0007 ,0009 ,0010  --------------------(空欄),0004 ,0011 ,0009 (空79行(空            欄),0005 ,0010 ,0009 (空80行(空            欄),0006 ,0009 ,0009 (空                 欄),0007 ,0005 ,0006 (空152行(空           欄),0008 ,0003 ,0003    以上で,(空,あるいは(空欄)乃至は数字で00を含む4  桁としているのは,文字化けを避けるために便宜上入れた  もので,数値そのものは2桁の範囲です。                   何度もトライしておりますができません。どうかよろしくお  願いします。なお,エクセルVBAによる方法もお教えいただ  ければ有難いです。

専門家に質問してみよう