データベース上の行を削除しても連番表示する方法

このQ&Aのポイント
  • ワークシート上にあるデータベースの任意行を削除しても、連続した番号を表示させる方法を教えてください。
  • VBAで作成したコードでデータベース上の行を削除しようとするとエラーが発生しています。解決方法を教えてください。
  • データベース上の各行に連番を振っていますが、削除後も連番が続くようにするための方法を教えてください。
回答を見る
  • ベストアンサー

データベース上の任意の行を削除しても連番にしたい

●質問の主旨 ワークシート上にあるデータベースの任意行を 直接マウス操作などで削除しようとするとき、 当該行のA列に入力されている番号について 削除されても、連続した番号を表示させ続けるようには、 どうしたら良いでしょうか? 下記コードを作成しましたが、上手くいきません。 どのように書き換えたら良いでしょうか? VBAをはじめてまだ2カ月程度の初心者です。 使用機種はWindowsVista、Excel2007です。 ご存知の方、どうぞご教示よろしくお願いします。 ●質問の補足 添付の画像のようにデータベース上の各行に1から順番に番号を 振っています。ところが下記のコードでは 「End Ifに対するIfブロックがありません」とエラーが返されます。 「If…Then…Else」ステートメントの「Else」のことを指しているので しょうか?ある参考書では「Else」は省略可と書いてあったので、 記述しなかったのですが… ●コード 'データベース上の任意行の削除について Sub Gyo_Sakujyo() Dim i As Integer Dim j As Range Dim DB_Kiten As Range 'Worksheets(1)にある任意行の直下の行のA列セルを変数jに短縮置換 Set j = Worksheets(1).Cells(i - 1, 1) 'データベースの基点をWorksheets(1)のA5セルに設定 Set DB_Kiten = Worksheets(1).Range("A5") '任意の行からワークシート上に書き込みがある領域から '1行分(見出し分)を差し引いた範囲において For i = i To DB_Kiten.CurrentRegion.Rows.Count - 1 'もし任意行が策された時、変数jに記入されている値は今の値から1を差し引く If Rows(i).Delete Then j.Value = j.Value - 1 End If Next End Sub

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

  • ベストアンサー
  • MARU4812
  • ベストアンサー率43% (196/452)
回答No.2

> ●質問の補足 >「End Ifに対するIfブロックがありません」 ヘルプでIf...Then...Else ステートメント の解説を読んで欲しいのですが、 単一行形式というものがあります。 [単一行形式] If Rows(i).Delete Then j.Value = j.Value - 1 [ブロック形式] If Rows(i).Delete Then   j.Value = j.Value - 1 End If VB では改行も意味を持ちますので注意して下さい。 ちなみに、 Sub test1()   For i = 0 To 2     If test2() Then          End If   Next End Sub Function test2() As Boolean   MsgBox "test2" End Function ではメッセージボックスが複数回表示されます。 >'もし任意行が策された時、 >If Rows(i).Delete Then 「Rows(i).Delete を"実行し"、その戻り値をBooleanで判断した時」 であって、ループで回した数だけ削除(策?)されると思います。 デバッグ作業をして下さい。1行1行ステップ実行して値を 確認したり、Debug.Print(イミディエイトウィンドウに出力)を利用 するなどして、何がどう処理されているかを全て把握して下さい。 'データベース上の任意行の削除について Sub Gyo_Sakujyo() Dim i As Integer Dim j As Range Dim DB_Kiten As Range Dim rngTemp As Range 'i = 2 'Worksheets(1)にある任意行の直下の行のA列セルを変数jに短縮置換 Set j = Worksheets(1).Cells(i - 1, 1) 'データベースの基点をWorksheets(1)のA5セルに設定 Set DB_Kiten = Worksheets(1).Range("A5") '任意の行からワークシート上に書き込みがある領域から '1行分(見出し分)を差し引いた範囲において Set rngTemp = DB_Kiten.CurrentRegion Debug.Print "For前データ確認" Debug.Print "CurrentRegion:" & rngTemp.Address Debug.Print "i:" & i Debug.Print "RowCount:" & DB_Kiten.CurrentRegion.Rows.Count For i = i To DB_Kiten.CurrentRegion.Rows.Count - 1   'もし任意行が策された時、変数jに記入されている値は今の値から1を差し引く   Set rngTemp = Rows(i)   Debug.Print "ループ内If実行"   Debug.Print "Delete対象:" & rngTemp.Address   Debug.Print "修正対象:" & j.Address   If Rows(i).Delete Then     j.Value = j.Value - 1   End If Next End Sub

dradra33
質問者

お礼

MARU4812様 ご回答ありがとうございます。お礼が遅くなり申し訳ありません。 偶然エクセルVBAのプログラマーの方と知り合うきっかけがあり、 同様の質問を直接したところ、 >「Rows(i).Delete を"実行し"、その戻り値をBooleanで判断した時」 >であって、ループで回した数だけ削除(策?)されると思います。 という感じMARU4812様と同じようなお答えをいただきました。 またNo.3のimogasi様のご回答にもあるように プログラムが出来たときの実行のきっかけについても 問われ、ワークシートのイベントに関する文献とその勉強を した方が良いとアドバイスをいただきました。 本件質問について、今のところ解決はできていませんが、 その知り合った方のアドバイスに基づいてプログラミングは 一旦止めて、その勉強をしたいと思います。 なお[単一行形式]、[ブロック形式]及びDebug.Print に関する アドバイスありがとうございました。 今後のプログラミングの参考とさせていただきます。

その他の回答 (2)

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.3

初心者がやるには難しい課題だと思う。 しかし原理的に考えて、全般的に振りなおすしかない。 質問では情況の説明がはっきりせず、コードのことばかり気を取られている。 添付画像などに頼らず文章で説明できるようになることが、プログラムの勉強になるはず。 (1)今のシートでの連番の情況(並び順は)は。中身的には連続しているが、シート上ではバラバラか。 昇順になっているのかどうか。 (2)バラバラになっているなら、指定している(削除した番号)以上の番号(の入っている)行は、1削除セル当たり、1引く ことをすべての行にわたって行う。 こういうのをロジックといい、この方法はほぼ全行に亘ってチェックする必要があり、できれば他に何か良い方法はないか考えるのが、中級者s以上の課題になると思う。 関数などでやる(ROW関数利用、順序が行番号と同じと決っている場合)と、削除と連動してくれるので面倒が無い。 関数でやれば良いと思うのでこの質問はVBAの練習としては不適当の課題。 ーー しかしこれ(削除)が1作業中に頻繁に行われるなら、削除ごとの時間がかかって、スムーズ感がうしなわれ大変かも。 ーー とりあえず削除サインを立てて、ブックを閉じる最後にまとめて振りなおすなどを考える(それでよければの場合だが)のでは。 こういうのは初心者には難しい(コードは簡単でも)考え方。 ーーー >直接マウス操作などで削除しようとするとき エクセルVBAでは行削除の操作をしたとき、それをとらえるイベント(勉強しましたか)が無かったと思う。 質問者は、このキッカケをどうしようというのだろう(プログラムが出来たとして、実行するキッカケ)。 そういうことも含めて、コード(どうせ初心者では我流しか出来ない)のことを気にせず、やりたいことの全般を文章で書いて(この点がこの質問は弱いと思う)識者に聞いてみたらどうです。 (1)処理単位 即時(都度何回もになり勝ち)とバッチ処理(1回が多い) (2)実行のキッカケ についていつも念頭に置くこと。 普通は利用者が実行操作をして1回限りが前提になっている場合が多いが。

dradra33
質問者

お礼

imogasi様ご回答ありがとうございます。 お礼が遅くなり恐縮です。 先日偶然にもエクセルVBAのプログラマーの方と お話する機会があって同様の質問をしたところ、 私が実行させようとしていることと、記述したコードとは 全く的外れだったようです。 その方から、ワークシートオブジェクトにおいて 実行するきっかけなどを勉強した方が良い、とのアドバイスも いただきました。 本件質問に関するプログラミングは一旦止めて、そういった 文献等を探すことから始めたいと思います。

回答No.1

A列には式「=ROW()-4」を設定しておく,というのではだめですか。

dradra33
質問者

お礼

Yune-Kichi様ご回答ありがとうございます。 Yune-Kichi様の >A列には式「=ROW()-4」を設定しておく という案も頭の中に入れておきます。 作成しているデータベースのひな型は 私案の段階なので試用するときにVBAで 作成できなければROW関数を用いたいと 思います。

関連するQ&A

  • エクセル 最終行からの連続コピー

    エクセルで最終行から上に連続する10行(最終行含む)をコピーしたいです。 途中、空白行が含まれている場合でも、最終行を特定し、コピーできるようにするには、下記のコードにどう手を加えたらよいでしょうか? どなたかアドバイスをお願いします。 Sub Test()   Dim i As Long   Dim j As Integer   Dim rng As Range   With ActiveSheet     'フィルタ     .Range("A1").CurrentRegion.AutoFilter Field:=1          '行選択     With .AutoFilter.Range       For i = .Cells(.Cells.Count).Row To 2 Step -1         If .Rows(i).Hidden = False Then           If rng Is Nothing Then             Set rng = .Rows(i)           Else             Set rng = Union(rng, .Rows(i))           End If           j = j + 1         End If         If j >= 10 Then Exit For       Next i       'コピー       If Not rng Is Nothing Then         rng.Copy Worksheets("Sheet2").Range("A1")         Beep       Else         MsgBox "該当行は存在しません。", 48       End If     End With   End With   Set rng = Nothing なお、コードはこちらを参考にさせていただきました。 http://okwave.jp/qa3552420.html?ans_count_asc=1

  • エクセル 最終行からの連続コピー

    * すぐに回答を! エクセルC20からI51までデータを1日1行ずつ入力します。 データが入力されている最終行から上に連続する10行(最終行含む)をコピーしたいのですが、最終行から10行上をどのように認識させたらいいのか、わかりません。Offsetなど試してみましたがダメでした。 よろしくお願いします。 Sub dataコピー() Dim i As Long Dim j As Integer Dim rng As Range '最後尾から10行前までを選択 With Worksheets("月").Range(Cells(20, 3), Cells(51, 10)) For i = Cells(Rows.Count, 1).End(xlUp).Row To -10? If rng Is Nothing Then Set rng = .Rows(i) End If j = j + 1 If j >= 10 Then Exit For Next i 'コピー If Not rng Is Nothing Then rng.Copy Range("M1") Beep Else MsgBox "該当行は存在しません。", 48 End If End With Set rng = Nothing End Sub コードはこちらを参考にしました ​http://questionbox.jp.msn.com/qa5440189.html

  • 他のシートの任意の列に1行おきに表示する

    よろしくお願いします。 下の構文ですと Worksheets("入力")の3列目5行目以降のデーターが Sheet2の同じ列(3列目)5行目以降に1行おきに表示されます。 これを Worksheets("入力")の3列目5行目以降のデーターを Sheet2の7列目5行目以降に1行おきに表示したいのですが どのように書き直せばよいでしょうか。 Private Sub Worksheet_SelectionChange(ByVal Target As Range) Dim i As Long, j As Long j = 5 With Worksheets("入力") For i = 5 To .Cells(Rows.Count, 3).End(xlUp).Row .Rows(i).Copy Worksheets("Sheet2").Cells(j, 1) j = j + 2 Next i End With End Sub

  • 条件に合った行を削除するマクロについて

    こんにちは 今、現在、とある条件にあった行を削除するマクロ作っているのですが、 インターネットを調べてみると後ろから探索して、1行ずつ消していくのがいいと書いてありました。 まぁ、その理屈はわかるんですが、それなら 「Unionでセルの範囲を結合してから、最後に一度に消してしまった方が速いのでは」 (消す作業が1度だけで済むから) と思い試してみたんですが、実際試したところ・・・ ものすごく遅かったです。 (ちなみに、1万件のデータで削除した行数は6000ほどでした) 何故Union結合だと遅いのでしょうか? 速いマクロを作成するには、やはり後ろから探索して、1行ずつ消していくしかないのでしょうか? 以下は試したマクロです。 (test が unionで試したマクロ、test2が後ろから1行ずつ削除したマクロ) Option Explicit Public Sub test() Dim r As Range Dim r1 As Range 'Cells.Replace "-", " " For Each r In Range("A2", Range("A65536").End(xlUp)) If r = r.Offset(1, 0) And r.Offset(0, 1) < r.Offset(1, 1) Then If r1 Is Nothing Then Set r1 = r Else Set r1 = Union(r1, r) End If End If Next r1.EntireRow.Delete ' r1.Select End Sub Public Sub test2() Dim r As Range Dim r1 As Range Dim i As Integer 'Cells.Replace "-", " " Application.ScreenUpdating = False For i = Range("A65536").End(xlUp).Row To 1 Step -1 If Cells(i, 1) = Cells(i + 1, 1) And Cells(i, 2) < Cells(i + 1, 2) Then Cells(i, 1).EntireRow.Delete End If Next Application.ScreenUpdating = True End Sub

  • E列が空白のとき、その空白行を削除し、番号を振り直す

    windows7 Excel2003でマクロ勉強中です。 あるサイトにE列が空白のとき、その空白行を削除し、番号を振り直すという コードがありました。 自分で作った表(表の最上段の2行は項目名が入っています。)で  実行すると「Rangeメソッドは失敗しました。Globalオブジェクト」と エラーが出ます。エラーはでますが、処理自体は正しく実行されます。 このエラーの原因と回避するにはどうしたらよろしいでしょうか。 Sub E列が空白のとき、その空白行を削除し、番号を振り直す() Dim i As Long, j As Long '行削除の処理 For i = Range("A" & Rows.Count).End(xlUp).Row To 1 Step -1 If Range("A" & i).Value <> "" And IsNumeric(Range("A" & i).Value) = True Then If Range("E" & i).Value = "" Then Rows(i).Delete End If End If Next '番号振りなおし処理 '’’Range("A" & Rows.Count).End(xlUp).Offset(1).Select For i = 0 To Range("A" & Rows.Count).End(xlUp).Row If Range("A" & i).Value = "番号" Then j = 1 ・・・・・ここでエラー発生 If Range("A" & i).Value <> "" And IsNumeric(Range("A" & i).Value) = True Then Range("A" & i).Value = j j = j + 1 End If Next ActiveSheet.Protect End Sub

  • ExcelVBAで行と列の検索

       A  B  C  D  E 1  コード あ  い  う  え 2  10  ○    ○ 3  20     ○  ○ 4  30          ○ 上記の表が5000件あります。Textbox1に入力し検索ボタンを押すと A列のコードを検索して一致する列の○のあるところの1行目の項目 をtextbox2に表示したいのですがうまく行きません。 よろしくお願い致します。 Private Sub CommandButton1_Click() '検索フォームボタン Dim i As Long Dim 最終行 As String Dim サーチ行 As Long Sheets(1).Activate 最終行 = Range("A1").End(xlDown).Row サーチ行 = 0 For i = 2 To 最終行 If TextBox1.Value = Range("A" & i) Then If Range("B" & i, "N" & i) = "" Then TextBox2.Text = Range("B1", "N1") サーチ行 = i Exit For End If End If Next If サーチ行 = 0 Then MsgBox TextBox1.Value & "データはありません。", vbInformation, "無し" End If TextBox1.SetFocus End Sub エラーはでません。データはありませんとなります。  

  • VBA 複数の行を挿入後、挿入以外を削除

    知恵をお借りください。 A10に5行分挿入、A13に2行分挿入、A14に1行分挿入、A16に2行分挿入 以下がコードです。 Dim n As Long n = Worksheets("Sheet1").Range("A1").Value With Worksheets("Sheet2") .Range("A10").Resize(n).EntireRow.Insert .Range("A10").Resize(n).EntireRow.Interior.Color = vbYellow .Activate End With Dim k As Long k = Worksheets("Sheet1").Range("A2").Value With Worksheets("Sheet2") .Range("A13").Resize(n).EntireRow.Insert .Range("A13").Resize(n).EntireRow.Interior.Color = vbRed .Activate End With Dim m As Long m = Worksheets("Sheet1").Range("A5").Value With Worksheets("Sheet2") .Range("A14").Resize(n).EntireRow.Insert .Range("A14").Resize(n).EntireRow.Interior.Color = vbGreen .Activate End With Dim ka As Long ka = Worksheets("Sheet1").Range("A10").Value With Worksheets("Sheet2") .Range("A16").Resize(n).EntireRow.Insert .Range("A16").Resize(n).EntireRow.Interior.Color = vbBlue .Activate End With マクロ実行後、行の並び方がバラバラになっています。 ↓イメージ図 https://mega.nz/#!yUwXHTLK!TSZvMJ1CaiTi-OoX-1j9IeNleuXesrzU5O7o2vG-svI 理想図に整えるにはどうすれば良いのでしょうか? また、マクロで行を挿入したら、不要な行を削除するコードも教えてくださればありがたいです。 ↓イメージ図 https://mega.nz/#!fMRDAKAJ!GHMpiagpn-O_0aaMhrHOozFd8WHHkSQzOS-fSCInw-g 宜しくお願いします。

  • Excel VBA 連番印刷

    昨日以下の質問をさせていただいた者です。 http://okwave.jp/qa/q8349562.html こちらで教えていただいた以下のコードに、 J2のセルに連番を振るコードを付け足したいと思い、 同じくこちらのサイトの過去の履歴にあった以下コードを参考にとやってみているのですが、 Next で指定された変数の参照が無効です。と言われてしまいます… 印刷部数の指定はいらず、sheet印刷のJ2セルに1から始まる連番を振りたいのです。 どのように修正をしたらいいのかご教示願います。 Sub Sample4() Dim i As Long, endRow1 As Long, endRow2 As Long, myArea1 As Range, myArea2 As Range Dim wS1 As Worksheet, wS2 As Worksheet, wS3 As Worksheet Set wS1 = Worksheets("DB") Set wS2 = Worksheets("印刷") Set wS3 = Worksheets("Sheet3") endRow1 = wS1.Cells(Rows.Count, "A").End(xlUp).Row Range(wS1.Cells(1, "A"), wS1.Cells(endRow1, "A")).AdvancedFilter Action:=xlFilterInPlace, unique:=True wS1.Range("A:A").Copy wS3.Range("A1") wS1.ShowAllData For i = 2 To wS3.Cells(Rows.Count, "A").End(xlUp).Row endRow2 = wS2.Cells(Rows.Count, "B").End(xlUp).Row If endRow2 > 9 Then Range(wS2.Cells(10, "B"), wS2.Cells(endRow2, "H")).ClearContents Range(wS2.Cells(10, "J"), wS2.Cells(endRow2, "J")).ClearContents End If wS1.Range("A1").AutoFilter field:=1, Criteria1:=wS3.Cells(i, "A") wS2.Range("B6") = wS3.Cells(i, "A") Set myArea1 = Range(wS1.Cells(2, "B"), wS1.Cells(endRow1, "H")).SpecialCells(xlCellTypeVisible) Set myArea2 = Range(wS1.Cells(2, "I"), wS1.Cells(endRow1, "I")).SpecialCells(xlCellTypeVisible) myArea1.Copy wS2.Activate ActiveSheet.Range("B10").Select Selection.PasteSpecial Paste:=xlPasteValues myArea2.Copy wS2.Activate ActiveSheet.Range("J10").Select Selection.PasteSpecial Paste:=xlPasteValues endRow2 = wS2.Cells(Rows.Count, "B").End(xlUp).Row 'Range(wS2.Cells(1, "A"), wS2.Cells(endRow2, "J")).PrintOut Next i wS1.AutoFilterMode = False wS3.Cells.Clear End Sub 連番印刷のコード Sub NumberPrint() Dim idx As Integer Dim res  res = Application.InputBox("印刷部数を入力してください", Type:=1)  If res > 0 Then   For idx = 1 To res    Range("AW3").Value = idx    ActiveSheet.PrintOut   Next idx  End If End Sub

  • Vlookup関数で行と列を両方Loopで回したい

    エクセル2010です。 Vlookup関数を使って、下記のようなコードを作りました。 行のLoopはできたのですが、列がわからなくて 1列ごと、50列まで書きました。 列のLoopはどうすればいいのでしょうか? よろしくお願いいたします。 Sub 毎月集計() Dim i As Byte Dim 範囲 As Range Dim myV As Variant Sheets("実績").Select Set 範囲 = Worksheets("2月").Range("B7:AZ20") For i = Application.InputBox("開始行を半角で入力してください。", Default:=123, Type:=1) To Application.InputBox( _ "最終行を半角で入力してください。", Default:=123, Type:=1) myV = Application.VLookup(Range("B" & i).Value, 範囲, 2, False) If IsError(myV) Then                Range("C" & i).Value = "0"         Else Range("C" & i).Value = myV End If myV = Application.VLookup(Range("B" & i).Value, 範囲, 3, False) If IsError(myV) Then Range("D" & i).Value = "0" Else Range("D" & i).Value = myV End If 以下省略 Next i End Sub

  • VBAで空白行を削除する

    VBAでリストの空白行を削除するための適当なコードを探しているのですがどんぴしゃのものが中々見つかりません。ご教授下さい。 ブックBのシートBのリストにはA2~AN●まで値が入っています。 別のブックAからVBAで値を取り出し貼り付けています。 いくつかの方法を試しました。 (1)ブックを開いたときに空白行を削除 Sub Auto_Open() '空白行を削除 Dim lRow As Long Dim i As Long lRow = Cells(Rows.Count, 1).End(xlUp).Row Application.ScreenUpdating = False For i = lRow To 2 Step -1 If Cells(i, 1).Value = "" Then Range(i & ":" & i).Delete End If Next i Application.ScreenUpdating = True End Sub 5分以上砂時計のままで結局終わりません。 強制終了させ再度ブックを開くと空白行は削除されているのですが、こんな動作では使うことができません。 (2)ブックAの値を貼り付けた後、空白行を削除し上書き保存する Sub エクスポート() Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Range(Cells(5, 7), Cells(79, 46)).Select Selection.Copy 'コピー Workbooks.Open Filename:="\\パス\ブックB.xlsm" '貼り付け先ファイルオープン Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False '貼り付け Dim lRow As Long Dim i As Long lRow = Cells(Rows.Count, 1).End(xlUp).Row Application.ScreenUpdating = False For i = lRow To 2 Step -1 If Cells(i, 1).Value = "" Then Range(i & ":" & i).Delete End If Next i Application.ScreenUpdating = True  '空白行を削除 ActiveWorkbook.Save '上書き保存 Application.Calculation = xlCalculationAutomatic Application.ScreenUpdating = True End Sub (3)空白行を削除の部分は以下のコードも試しました Worksheets("SheetB").Range("A1").Select Set currentCell = Worksheets("sheetB").Range("A1") Do While Not IsEmpty(currentCell) Set nextCell = currentCell.Offset(1, 0) If Not IsEmpty(currentCell) Then 'カレントセルが空白でなく、 If IsEmpty(nextCell) Then '次のセルが空白のとき nextCell.EntireRow.Delete End If End If Set currentCell = currentCell.Offset(1, 0) Loop '空白行削除 宜しくお願い致します。

専門家に質問してみよう