VBAの値引き渡し処理に関して、教えて下さい。

このQ&Aのポイント
  • VBAを勉強中の者が、特定の条件を満たす行以外を削除する方法についての質問です。
  • エクセルシートの中から、特定の条件を満たす行のみを抽出し、それ以外の行を削除したいと考えています。
  • D列でmaxValの値を持っている行以外を削除する方法を教えてください。
回答を見る
  • ベストアンサー

VBAの値引き渡し処理に関して、教えて下さい。

すいません。 VBAを勉強中の者です。 あるシステムの開発を会社で命じられ、VBAで必死に構築しております。 いくつかの問題は、自己解決したのですが、下記の部分が、どう調べても分かりません。 教えて下さい。 よろしくお願いいたします。 =========== <説明> 添付の様なエクセルシートがあります。(実際は、もっと行数も列数も多いですが。) 点数が一番高い会社(この例では、C社)のみのデータ行のみを抽出して、それ以外の行を消したいと考えております。 シート名を、ranking とすると、とりあえず、下記の様なコードにて、最大値を求めると思います。 ************* Public Sub ranking_ope() '高順位を選択。 Sheets("ranking").Select Dim maxVal As Long 'Excelのワークシート関数を使う With Application.WorksheetFunction 'E列に記入された数値の最大値を求める maxVal = .Max(Range("D:D")) End With End Sub ************************** 上記の動作を確認しましたが、ここまでは、OKです。 <質問> お聞きしたいのは、この先です。 D列で、maxValの値を持っている会社(この場合はC社)以外の行を消したいと考えております。 申し訳ないのですが、コードと一緒に教えて下さい。 思うに、別のプロシージャーを作成して、そこに、maxValを「値引き渡し」で引き継いで、D列の値が、maxVal以外の場合は、削除すると言う事にすると思うのですが、どうも「値引き渡し」が出来ていない様です。 よろしくお願いいたします。

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

  • ベストアンサー
  • SI299792
  • ベストアンサー率48% (716/1482)
回答No.4

1.その通りです。受け渡す変数が複数ある時は、「,」で区切ります。長くなるようなら、「_」で次の行に書きます。  勉強のために、値引き渡しの方法が知りたいのであって、動けば何でもいいわけではないのですね。 2.ごめんなさい。読み間違えました。お書きの通り、   If Cells(Row, "D") <> maxVal Then に直してもいいし、   If Cells(Row, "D") < maxVal Then にしてもいいです。 後、最終行を得るやり方も、必要となります。私は、   RowEnd = [D4].End(xlDown).Row としました。簡単なので、私は愛用していますが、データが無いと誤動作する。途中に空白があるとそこで止まるという弱点があります(その弱点を利用して、空白後に別の表がある時に使えます)。データが無い、空白データの可能性がある場合、他の人がやった   RowEnd = Range(Rows.Count, "D").End(xlUp).Row を使います。 受け渡し変数が2つある事例です。 ' Sub Macro4() '   Dim RowEnd As Long   Dim maxVal As Long   Dim Row As Long '   Sheets("ranking").Select   RowEnd = [D4].End(xlDown).Row '   ranking_ope2 RowEnd, maxVal '   For Row = RowEnd To 5 Step -1 '     If Cells(Row, "D") < maxVal Then       Rows(Row).Delete     End If   Next Row End Sub ' Public Sub ranking_ope2(RowEnd As Long, _             maxVal As Long) '   Dim DRange As Range '高順位を選択。   Set DRange = Range("D4:D" & RowEnd)   maxVal = WorksheetFunction.Max(DRange) End Sub

yujin1202
質問者

お礼

御礼が遅くなり失礼しました。 (ベストアンサーを選んだ際に、お礼のメッセージも書いたのですが、反映されなかった様です。。。) 本件、解決いたしました。 ありがとうございました。

その他の回答 (3)

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

質問の趣旨と違うと思うが 例データ 社名 住所 点数 A 東京 70 B 神奈川 65 C 北海道 80 D 埼玉 52 E 大阪 35 F 奈良 80 最後1行追加した。 データーフィルターのTOP1を抽出の操作をして、マクロの記録。 Sub Macro1() ' ' Macro1 Macro ' Range("A1:C7").Select Selection.AutoFilter ActiveSheet.Range("$A$1:$C$7").AutoFilter Field:=3, Criteria1:="1", _ Operator:=xlTop10Items End Sub ーー 結果 社名 住所 点数 C 北海道 80 F 奈良 80 難しいことを考えるよりこういう方法を生かしては。 == 初歩的で素直な方法は、点数列の最大値を求める。 最下行から、ForNextで上行方向に最大値かどうかIFで判定し、同じ値以外の行は行削除するとか。 言いたいことは、(自分の最初の思い付きを置いておいて、折角多数の人に聞くのだから)大切なのは、他人のよさそうなやり方の探求と真似だと思う。

  • SI299792
  • ベストアンサー率48% (716/1482)
回答No.2

Sub の中にDim で変数を書いても、そのサブルーチン専用変数で、他に渡すことはできません。()に受け渡しの変数を宣言する必要があります。 ' Option Explicit ' Sub Macro1() '   Dim maxVal As Long   Dim Row As Long '   ranking_ope maxVal '   For Row = [D4].End(xlDown) To 5 Step -1 '     If Cells(Row, "D") = maxVal Then       Rows(Row).Delete     End If   Next Row End Sub ' Public Sub ranking_ope(maxVal As Long) ' Dim maxVal As Long は消しておく 又は、関数にします。 ' Sub Macro2() '   Dim maxVal As Long   Dim Row As Long '   maxVal = Ranking '   For Row = [D4].End(xlDown) To 5 Step -1 '     If Cells(Row, "D") = maxVal Then       Rows(Row).Delete     End If   Next Row End Sub ' Function Ranking() As Long '   Sheets("ranking").Select   Ranking = WorksheetFunction.Max(Range("D:D")) End Function ’ グローバル変数にするという方法もありますが、お勧めできない方法なので割愛します。 ただ、プロシージャーを別にする必要はないと思います。1本で済みます。 それど、D列全てを見ているので、時間がかかります。こうすれば速くなります。 ' Sub Macro3() '   Dim RowEnd As Long   Dim maxVal As Long   Dim DRange As Range   Dim Row As Long '   Sheets("ranking").Select   RowEnd = [D4].End(xlDown).Row   Set DRange = Range("D4:D" & RowEnd)   maxVal = WorksheetFunction.Max(DRange) '   For Row = RowEnd To 5 Step -1 '     If Cells(Row, "D") = maxVal Then       Rows(Row).Delete     End If   Next Row End Sub

yujin1202
質問者

補足

早速のご回答を誠にありがとうございます。 解釈しながら、試しております。 大変、勉強になります。 検証まで、もうしばらく時間が掛かりそうなのですが、 2点だけ確認をさせて下さい。 1. > ()に受け渡しの変数を宣言する必要があります。 「受け渡しの変数を宣言」は、下記で行っていると言う理解で宜しいでしょうか? > Public Sub ranking_ope(maxVal As Long) 2. >If Cells(Row, "D") = maxVal Then >Rows(Row).Delete Macro1()に上記記載がありますが、今回は、最高得点以外は行削除すると言う風にしたいので、下記の様になりませんか? (イコールではなく。) ========= If Cells(Row, "D") <> maxVal Then Rows(Row).Delete ======== よく分かっておらず、質問ばかりで申し訳ございませんが、教えて下さい。 よろしくお願いいたします。

  • mt2015
  • ベストアンサー率49% (258/524)
回答No.1

サンプルです。 D列の値が80未満の行をデータが入っている一番下の行から5行目まで順番に探し、削除します。 列を削除する場合、下から探していって削除がコツです(検索範囲が変わらないため)。 Sub main()   maxVal = 80   MsgBox fDel(maxVal) & "行削除" End Sub Function fDel(nMax) As Long   For nRow = Cells(Rows.Count, 4).End(xlUp).Row To 5 Step -1     If Cells(nRow, 4) < nMax Then       Rows(nRow).Delete Shift:=xlUp       fDel = fDel + 1     End If   Next nRow End Function

関連するQ&A

  • VLOOKUP関数と同じことをVBAでおこなうには

     初めまして、当方VBAの素人です。よろしくお願いします。  同じような質問で、このようなVBAを見つけました。 Sub Macro1() For n = 2 To 5 '処理するSheet2の行数範囲 a = Sheets("Sheet2").Cells(n, 1) 'aにA列の値を代入 For m = 2 To 5 '検索するSheet1の行数範囲 If Sheets("Sheet1").Cells(m, 1) = a Then 'Sheet2のA列の値とSheet1のA列が一致した場合 v = Sheets("Sheet1").Cells(m, 2) 'vにB列の値を代入 Sheets("Sheet2").Cells(n, 2).Value = v 'Sheet2のB列に値を入力 Exit For '値が見つかったのでForを終了 End If Next Next End Sub このVBAではSheet2での検索、入力が列になるのですが、列でなく、行でできないでしょうか。できればSheet1のB列の値をSheet2の1行で検索、Sheet2の2行に入力されるだけではなく、Sheet1のC列の値をSheet3の1行で検索、Sheet3の2行に入力されるようにしたいと思います。  解る方、よろしくお願いします。

  • VBAで困っています。

    VBAで比較ツールを作っています。2つのワークシートを比較し、同じセルの位置にある値を比較し、値が異なっていれば色を変えるというものです。行をキー(1行、2行、3行・・・)として2つのワークシートですべてのキー行のセルの値が一致する列同士を比較する方法があるのですが、キーを1個でも100個でも指定した場合のプログラム構造を知りたいのです。 お力をお貸しください。 Sub DF() Dim Before As Range Dim After As Range Before = Worksheets("Sheet1").UsedRange.Value After = Worksheets("Sheet2").UsedRange.Value キーとなる行数をカウント   カウントした行を最大値を変数に設定   ・・・・   ・・・・   ・・・・ End Sub

  • エクセルVBA:繰り返し処理について

    エクセルVBA初心者です。どうかご指導お願いします。 シート1に入力されたデータベースがあります。 B列には氏名が入力されています。 B2の値で絞りこんで、シート2に貼り付け、 B3の値で絞りこんで、シート3に貼り付け、 B4の値で絞り込んでシート4に貼り付けてB列の値が""(空白)になるまで繰り返すコードの書き方を教えてください。 さらに、B列には、当然同じ氏名が何回も入力されているので、前に一度出た人はパスするというようにしたいのです。 下記コードは、「B2の値で絞りこんで、シート2に貼り付け」だけをしたものですが、このコードを応用して作りたいのです。ご指導お願いします。 Sub test01()  With sheets("sheet1")Range("A1")   .AutoFilter field:=2, Criteria1:=Range("B2")   .CurrentRegion.Copy Destination:=Sheets("Sheet2").Range("A1")   .AutoFilter  End With End Sub

  • エクセルVBA if、Elseifの使い方について

    調べたり、試行錯誤したのですが分からないので教えてください。 A列の最大値により表示されるメッセージを場合分けします。 (1)最大値が1~9の場合→「終了します」のメッセージを表示させる。 (2)最大値が0の場合  →「該当なし。シートを削除しますか?」のメッセージを表示させる。 (3)最大値が10の場合 →「すべて選択しています。シートを削除しますか?」のメッセージを表示させる。 メッセージをクリックした結果 (1)「はい」をクリックして終了。 (2)「はい」をクリックすれば、シートを削除。「いいえ」をクリックして終了。 (3)「はい」をクリックすれば、シートを削除。「いいえ」をクリックして終了。 'メッセージ Dim maxval As Long maxval = Application.Max(sheet1.Range("A:A")) If maxval >= 1 And maxval <= 9 Then MsgBox " 終了します" ElseIf maxval = 0 And vbYes = MsgBox("該当なし。シートを削除しますか?", vbYesNo) Then Application.DisplayAlerts = False sheet1.Delete Application.DisplayAlerts = True ElseIf maxval = 10 And vbYes = MsgBox("すべて選択しています。シートを削除しますか?", vbYesNo) Then Application.DisplayAlerts = False sheet1.Delete Application.DisplayAlerts = True End If End Sub (1)最大値が1~9の場合は成功します。 (2)(3)最大値が0の場合や10の場合に、「該当なし。シートを削除しますか?」と「すべて選択しています。シートを削除しますか?」の両方が、表示されてしまいます。 (2)(3)の場合に、それぞれのメッセージしか表示されないようにするにはどうしたらよいのでしょうか。 よろしくお願いします。

  • VBA 繰り返し処理について

    VBA初心者で書籍などで基本的な繰り返し処理のサンプル文を読んだのですが、 自分がやりたいことをどう繰り返し文で実現すればいいのかよくわかっていません。 やりたいことは以下なのですが、繰り返し文についてご教授ください。 Excel ファイルイメージ A列 B列 C列 1    11    A 1    12    B 1    13    A 2    21    C 2    22    B 2    23    B ・・・ →このファイルイメージを参考にご説明すると、A列で同じ値分 ループを回し、C列の値によって一つの値に絞り込むことを実行 したいです。 例えば、 A列が1で、C列にA,B,Aが存在した場合、Aが二つあるので B列の値が最大の行(例:13)のD列にAという値を設定する。

  • Excel VBA リストボックスの複数列表示の方法について

    すいません、エクセルVBAのユーザーフォームのリストボックスの表示方法について質問があります。 シートのセルに    A列   D列   G列 1行 りんご  赤   120円 2行 みかん  黄   130円 3行 すいか  緑 110円 4行 りんご  赤 160円 . ・・・  ・   ・・・ . と、50行まで値を入れます。 VBAでユーザーフォームを挿入し、 Private Sub UserForm_Initialize() With ComboBox1 .AddItem "りんご" .AddItem "みかん" .AddItem "すいか" End With End Sub でコンボボックスの値を設定し、次に Private Sub ComboBox1_Change() Dim i As Integer For i = 1 To 50 If Cells(i, 1).Value = ComboBox1.Value Then With ListBox1 .ColumnCount = 3 .AddItem Cells(i, 1) End With End If Next i End Sub このときコンボボックスと同じ値の行について、 リストボックスにA列、D列、G列を表示させるにはどうしたらいいのでしょうか。 例えばコンボボックスで「りんご」を選択したときに、 リストボックスを りんご 赤 120円 りんご 赤 160円 と表示させたいのですが、 .AddItem Cells(i, 1) では一列だけしか表示できません。 Rowsorceを使ってみたりしましたが、どうにもうまく出来ませんでした。 よろしくお願いいたします。

  • VBA【初歩的な質問】

    エクセルシートのA列にホームページの名前、B列にそのページのアドレスが入力されております。 A列のページ名にハイパーリンクの情報を結び付けて、B列を削除したいです。 ※A列の名前が青くなっていて、クリックするとそのページに飛んでいくことができて、B列は空白 そのVBAを教えて頂けると助かります。 ページによって最終行が異なるので、最初に最終行を出して、For i で繰り替えしたらいいのでしょうか? HYPERLINKS.Addメソッドというのを使えばいいと思ったんですが、うまくいきませんでした。 Option Explicit Sub Sample() Dim i As Long '1行目からA列の最終行まで繰り返す For i = 1 To Range("A" & Rows.Count).End(xlUp).Row With ActiveSheet.Hyperlinks .Add Anchor:= End With Next i End Sub

  • VBAで条件式について

    EXEL(VBA)で例えば、A列のデータが入っている行までの中で数値(x)が  x<2 ならばセルに色をぬる。そして空白セルと x>2ならば色をぬらない。 という条件式は、どうしたらいいのですか? Sub InteriorColor() For j= 5 to 21 worksheets(j).activate For i = 1 to 40 '30から40行ぐらい While cells(6+i,6)<>"" If(cells(6+i,6).value<2) Then ’6列7行目から  with selection.interior .Colorindex=45 .patern=xlsorid End with Wend End if Next i Next j End sub ということを連続していない列(5列ぐらい)に対してします。 同じ命令文になる部分もあるので簡潔にしたいという希望もあります。 上部の命令では無限ループの可能性があり実行が止まりません。 どのように記述したらいいのですか? また、同じブックのシート25枚のうち5枚目から21枚目に対して処理します。 5から21までのシートの間で関係ないシートが7枚目と10枚目と15枚目にあります。それを省いての処理もあれば教えてください。

  • VBA 最終列に入力された値の表示について

    VBAで最終列に入力された値の表示について教えてください。 例えば10行目の10列目(J列)に”123”と入力された値をセル”D1”に表示させたいのですがどのようにすればよいのでしょうか。 A列の最終行については Private Sub Worksheet_Change(ByVal Target As Range) Dim r As Long r = Cells(Rows.Count, 1).End(xlUp).Row Range("D1").Value = Cells(r, 1).Value End Sub でうまく表示できたのですが、最終列についてなかなかうまくいきません。 どなたかご指南ください宜しくお願いします。

  • VBAで列全てに式を入れたいんです。

    エクセルで 例えばセルA1,B1,C1を選択して 3つのセルの値をD1に値としてコピーする事は出来ませんか? A1,B1,C1はVBAで得た値です。 関数で1つにすると、もう一度コピーして値として 貼り付けなけねばなりませんので・・・ VBAは他の方に作成して頂いたので、 知識としてはありません。 VBAでの追加の仕方があればお教え下さい。 下記の回答を頂きまして 上手くいったのですが、 その式を、列全てで行うのはどうすればいいのでしょうか? 「 次のコードをEnd Subの上の行に挿入してください With Sheets("シート名") .Range("D1") = .Range("A1") & .Range("B1") & .Range("C1") End with 」 すみません。誰かお教え下さい。

専門家に質問してみよう