質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

2回答

2305閲覧

[Excel VBA]空白行を上方向に削除して詰める

syu2048

総合スコア22

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2022/02/21 08:57

前提・実現したいこと

ある発注機関の発注機関コードおよび組織名をまとめたExcelファイルから、MySQLにあるテーブル「t_発注機関」の挿入・更新・削除を行うSQL文を新しいシートに書き出すマクロを作成しています。

EXCELファイルのテーブルは以下の通りです。
4列目が更新する組織名、5列目がINSERT/UPDATE/DELETE文を作成するかを判断する項目です。
5列目で「-」はチェック済、空白セルは未チェックを意味しています。

ID発注機関コード取引先w_取引先チェック
111111AAA-
222222BBBnew_BBB名称変更
333333CCC 削除
444444DDD 新規設置
555555EEE  
666666FFF 新規設置

このテーブルから、新しいシートに以下のようなSQL文が出力されるようにし、
5列目が「-」または空白の時に作成される空白セルを削除し、上方向に詰めるようにしたいです。

  • UPDATE t_発注機関 SET 取引先 = 'new_BBB' WHERE id = '2';
  • DELETE FROM t_発注機関 WHERE id = '3';
  • INSERT INTO t_発注機関 VALUES ('4','44444','DDD',);
  • INSERT INTO t_発注機関 VALUES ('6','66666','FFF',);

発生している問題・エラーメッセージ

マクロを実行すると、新しいシートに書き込み、途中の空白行は上詰めで削除されるのですが、
以下のように、先頭行の空白セルが削除されずに残ってしまいます。

  • (空白)
  • UPDATE t_発注機関 SET 取引先 = 'new_BBB' WHERE id = '2';
  • DELETE FROM t_発注機関 WHERE id = '3';
  • INSERT INTO t_発注機関 VALUES ('4','44444','DDD',);
  • INSERT INTO t_発注機関 VALUES ('6','66666','FFF',);

該当のソースコード

作成したソースコードは以下の通りです。

html

1Option Explicit 2 3Sub createSql() 4 With ActiveSheet 5 '新しいSheetの作成 6 Dim newsheet As Worksheet 7 Set newsheet = Worksheets.Add 8 9 'SQL文の作成 10 Dim sql As String 11 Dim i As Long 12 13 '条件分岐 14 For i = 2 To .Cells(Rows.Count, 1).End(xlUp).Row 15 If .Cells(i, 5) = "名称変更" Then 16 sql = "UPDATE t_発注機関 SET " & "取引先 = '" & Cells(i, 4) & "' WHERE id = " & Cells(i, 1) & ";" 17 18 ElseIf .Cells(i, 5) = "新規設置" Then 19 sql = "INSERT INTO t_発注機関 VALUES " & "('" & Cells(i, 1) & "','" & Cells(i, 2) & "','" & Cells(i, 3) & "')" & ";" 20 21 ElseIf .Cells(i, 5) = "削除" Then 22 sql = "DELETE FROM t_発注機関 WHERE id = " & Cells(i, 1) & ";" 23 24 ElseIf .Cells(i, 5) = "-" Then 25 sql = "" 26 27 Else 28 sql = "" 29 30 End If 31 32 '新しいSheetに書き込み 33 newsheet.Cells(i - 1, 1).Value = sql 34 35 Next 36 37 '空白セルを上詰め削除 38 Dim MyRng As Range 39 Set MyRng = ActiveSheet.UsedRange '処理する範囲を選択 40 MyRng.SpecialCells(xlCellTypeBlanks).Delete Shift:=xlShiftUp '範囲に含まれる空白行を削除 41 42 End With 43 44End Sub 45

試したこと

一行目の空欄を無視するように設定していることが考えられますが、一行目から始める方法が分からず困っています。
書き込むセルを最初から指定するコードを追加するほうがよろしいでしょうか。
良いアイデアがありましたら、ご教示いただきますよう、何卒よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

空のSQL(sql = "")も出力して、後からそれを削除するより、最初から空のSQLは出力しないようにすればいいのでは。

また、sqlに代入する行の Cells.Cellsというようにドットが必要です。ないと、ActiveSheetが対象になりますが、この時点では、newsheet がActiveSheetになりますので。

あと、If Then ElseIf Then を使うより、 Select Case の方がスッキリすると思います。

vba

1Sub createSql() 2 With ActiveSheet 3 '新しいSheetの作成 4 Dim newsheet As Worksheet 5 Set newsheet = Worksheets.Add 6 7 'SQL文の作成 8 Dim sql As String 9 Dim i As Long, j As Long 10 11 '条件分岐 12 For i = 2 To .Cells(Rows.Count, 1).End(xlUp).Row 13 Select Case .Cells(i, 5) 14 Case "名称変更" 15 sql = "UPDATE t_発注機関 SET " & "取引先 = '" & .Cells(i, 4) & "' WHERE id = " & .Cells(i, 1) & ";" 16 Case "新規設置" 17 sql = "INSERT INTO t_発注機関 VALUES " & "('" &. Cells(i, 1) & "','" & .Cells(i, 2) & "','" & .Cells(i, 3) & "')" & ";" 18 Case "削除" 19 sql = "DELETE FROM t_発注機関 WHERE id = " & .Cells(i, 1) & ";" 20 Case "-" 21 sql = "" 22 Case Else 23 sql = "" 24 End Select 25 26 '新しいSheetに書き込み 27 If sql <> "" Then 28 j = j + 1 29 newsheet.Cells(j, 1).Value = sql 30 End If 31 Next 32 End With 33End Sub

投稿2022/02/21 09:57

編集2022/02/21 10:16
hatena19

総合スコア34362

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

syu2048

2022/02/22 00:42

回答ありがとうございます。 空のSQLをそもそも書き込まないようにするというのが思いつかなかったので、 気づくことができ助かりました。 また、select case と if then の違いがいまいち理解しきれていなかったので、このコードをきっかけに分かったと思います。 こちらをベストアンサーとさせていただきます、ありがとうございました。
guest

0

Set MyRng = ActiveSheet.UsedRange '処理する範囲を選択
ActiveSheet.UsedRange が 親切に一番上の空白はUsedしていないので、
2行目から範囲として認識するのかな?
で、
その範囲に対して
MyRng.SpecialCells(xlCellTypeBlanks).Delete Shift:=xlShiftUp '範囲に含まれる空白行を削除
するから、
一番上が空白行なら、MyRngの範囲に入っていないので、削除されないとか?

ActiveSheet.UsedRange.Select すると、イメージがわくかなぁ。
イメージ説明

外していたらスミマセン。何かの参考となれば・・・・

投稿2022/02/21 09:29

ken3memo

総合スコア132

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ken3memo

2022/02/21 09:35

i で 行がわかるので、 Set MyRng = ActiveSheet.Range("A1:E" & i) とか
syu2048

2022/02/22 00:45

回答ありがとうございます。 Excelで同じ動作を確認しました。 おそらくExcelのおせっかいで上の空白を読み込まないようにしたのかもしれませんね。 範囲の取り方はよく考えながら行うようにします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問