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

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

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

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

Q&A

解決済

2回答

2009閲覧

[VBA]データ抽出がうまくいかないので教えてください

MaryCocoon

総合スコア13

VBA

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

0グッド

1クリップ

投稿2018/12/09 04:21

前提・実現したいこと

VBAで値域[zmin,zmax]にあるデータを抽出したい

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

コンパイルは問題なくいくが、望む結果が得られておらず、どこが問題なのかもわからない

該当のソースコード

Sheets(sht_nm).Select i = 5 ii = 3 While IsEmpty(Cells(i, 2).Value) = False If Cells(i, 2).Value > zmin And Cells(i, 2).Value < zmax Then xx = Cells(i, 1).Value zz = Cells(i, 2).Value Sheets("抽出データ").Select Cells(ii, 1).Value = xx Cells(ii, 2).Value = zz Sheets(sht_nm).Select ii = ii + 1 End If i = i + 1 Wend

試したこと

sht_nm, 抽出データsheetは作ってあり、初期セル(cells(5,1), cells(5,2))にはちゃんとデータは入っています。しかし、実行すると抽出データsheetにはなにも出力されず、処理が終了してしまいます。理由はwhileのループの中にあると思うのですが、わからないので教えていただきたいです。

補足情報(FW/ツールのバージョンなど)

excelは2013ver.

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

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

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

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

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

1T2R3M4

2018/12/09 04:42

zmin,zmaxはどこで定義してますか。
MaryCocoon

2018/12/09 05:25

sht_nm = Application.InputBox("sheet名") zmin = Application.InputBox("最小値", "zmin") zmax = Application.InputBox("最大値", "zmax") を上述のソースコードの前にいれています
hatena19

2018/12/09 07:04

その変数の宣言、代入も含めて、コード全体を提示してください。
guest

回答2

0

VBAは型をある程度自動変換してくれますが、今回のケースは型をしっかり意識する必要があります。

例えば以下のコードを見てzminはv~にどんな結果(True/False)が入るか予想してみてください。

vba

1Private Sub VariantStringDoubleCompareTest() 2 Dim zmin As Variant 3 zmin = CVar("1") 'Variant型として扱わせる 4 5 Dim v As Variant 6 v = CVar(1) 'Variant型として扱わせる 7 8 Dim zminはvより小さい As Boolean 9 Dim zminはvと同じ As Boolean 10 Dim zminはvより大きい As Boolean 11 12 zminはvより小さい = (zmin < v) 13 zminはvと同じ = (zmin = v) 14 zminはvより大きい = (zmin > v) 15 16 Stop 'ブレークポイント 17End Sub

恐らく

変数
zminはvより小さいFalse
zminはvと同じTrue
zminはvより大きいFalse

となると予想されたかと思います。

では実際の結果を見てみると以下のようになります。
(結果の表示にはローカルウィンドウを使っています。メニューバー→表示→ローカル ウィンドウ)

イメージ説明

このように、型を意識せず比較演算をすると、意図しない結果となることがあります。


今回の対処としては、zminzmax設定時のApplication.InputBoxの引数にTypeを指定し、数値のみ入力可能にしてあげると良いでしょう。

Office TANAKA - Excel VBA Tips[実は奥が深いInputBox]


蛇足

○○.Select及び、親のないCellsを使うと今どこで作業しているかがわかりにくくなってしまいます。

そのため、親のWorksheetを変数に取っておき、その変数経由で操作するとより堅牢になります。

ただ、親のWorksheetから辿ると記述が煩雑になる場合も多いため、さらに一歩進めて、Rangeそのものを扱う手もあります。

vba

1'Range操作メインにした場合 2 3i = 5 4ii = 3 5 6'現在処理中のデータシート 7Dim dataSheet As Worksheet 8Set dataSheet = Sheets(sht_nm) 9 10Dim currentDataCell As Range '=Cells(i, 1) 11Set currentDataCell = dataSheet.Cells.Item(i, 1) 12 13Dim v As Variant '= Cells(i, 2).Value 14v = currentDataCell.Offset(, 1).Value 15 16 17'「抽出データ」ワークシート 18Dim extractSheet As Worksheet 19Set extractSheet = Sheets("抽出データ") 20 21Dim outputCell As Range 'Sheets("抽出データ").Range(Cells(ii, 1), Cells(ii, 2)) 22Set outputCell = extractSheet.Cells.Item(ii, 1).Resize(, 2) 23 24Do Until IsEmpty(v) 25 If zmin < v And v < zmax Then 26 outputCell.Value = currentDataCell.Resize(, 2).Value 27 Set outputCell = outputCell.Offset(1) 'ii = ii + 1 28 End If 29 Set currentDataCell = currentDataCell.Offset(1) 'i = i + 1 30 v = currentDataCell.Offset(, 1).Value 31Loop

投稿2018/12/09 07:07

imihito

総合スコア2166

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

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

MaryCocoon

2018/12/09 12:38

imihito さん、ありがとうございました。 型の重要性とrangeを用いた方法、勉強になりました。 教えていただいたpgを精読して、より理解を深めたいと思います。 取り急ぎお礼申し上げます。ありがとうございました。
guest

0

ベストアンサー

変数の宣言、型に間違いがなければ、そのロジックでいいと思います。

シートのSelectは遅くなるだけで不必要なので、使わない方法を覚えましょう。

vba

1Public Sub Test() 2 Dim sht_nm As String 3 Dim zmin As Long, zmax As Long 4 Dim i As Long, ii As Long 5 Dim xx, zz 6 7 sht_nm = Application.InputBox("sheet名") 8 zmin = Application.InputBox("最小値", "zmin") 9 zmax = Application.InputBox("最大値", "zmax") 10 11 i = 5 12 ii = 3 13 While IsEmpty(Sheets(sht_nm).Cells(i, 2).Value) = False 14 zz = Sheets(sht_nm).Cells(i, 2).Value 15 If zz > zmin And zz < zmax Then 16 xx = Sheets(sht_nm).Cells(i, 1).Value 17 Sheets("抽出データ").Cells(ii, 1).Value = xx 18 Sheets("抽出データ").Cells(ii, 2).Value = zz 19 ii = ii + 1 20 End If 21 i = i + 1 22 Wend 23End Sub

もっとスマートな書き方はありますが、
とりあえず元のコードを活かして書き換えてみました。

追記
imohitoさんがすでにスマートな書き方を回答されてました。(;^ω^)

投稿2018/12/09 07:25

編集2018/12/09 07:32
hatena19

総合スコア33699

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

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

MaryCocoon

2018/12/09 12:42

hatena19 さん、ありがとうございました。 select sheetを使わないとこんなにも処理が速くなるのですね。驚きました。 今後変数の宣言をもっとしっかり理解してよりスマートな書き方を覚えていけるよう努力してまいります。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問