• ベストアンサー

Excel VBA セル位置が取得できません

条件1の時、セル位置を変数(gyo1)に代入し、 条件2の時、セル位置を変数(gyo2)に代入。 その後、countif(gyo1:gyo2)として、 その数値を別のセルに表示させる。 という構文を作りたいと思っています。 しかし、adressプロパティを記述しても、「オブジェクトが必要です」とエラーが出てしまいます。 (expressionをSelectionに変えるとエラーは出ないのですが、この違いや意味ってなんでしょうか。) さらに、この構文はFor文で繰り返しているのですが、 最初にgyo1の値が「A2」となっても、次の繰り返し時、条件が一致したても、gyo1が更新されず、「A2」のままだったりします。 (イメージでは、「A10」とか、A列を下に移動していくはずです。) また、gyo1,gyo2の変数宣言は、どのようにすれば良いでしょうか。 以下、作成中のコードを記述します。 力を貸してくださいませ。よろしくお願いいたします。 row = 2 If Cells(row, 1) <> Cells(row - 1, 1) Then gyo1= Selection.Address(Cells(row, 1)) End If If Cells(row, 2) <> Cells(row - 1, 2) Then gyo2 = Selection.Address(Cells(row, 2)) End If Cells(row,5).value = countif(gyo1:gyo2)

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

  • ベストアンサー
  • pulsa
  • ベストアンサー率57% (34/59)
回答No.4

すいません >条件1の時、セル位置を変数(gyo1)に代入し、 >条件2の時、セル位置を変数(gyo2)に代入。 から、てっきりgyo1にCellsを指定すれば、そのRangeがgyo1に代入されると思い込んでいました   Dim MyRow As Integer   Dim gyo1 As Range   Dim gyo2 As Range ・ ・ ・       Set gyo1 = Cells(MyRow, 1)     Set gyo2 = Cells(MyRow, 2)     Cells(MyRow, 5).Value = WorksheetFunction.CountIf(Range(gyo1, gyo2), ">0") gyo1・gyo2 がどのように宣言されているかわかりませんが、VariantかRangeで宣言してください Set でRangeObjectと指定するのを忘れていました 申し訳ありません あと、前回言っていませんが、Rowは元からエクセルVBAに含まれている変数名ですので、別な変数名にするのをお勧めします(例はMyRowです)

Trader-Aki
質問者

お礼

おかげさまで問題解決できました。(^^) 何度もアドバイスいただき、本当にありがとうございました。 もっと自己学習に努め、VBAを使いこなせるよう目指します。

その他の回答 (3)

  • pulsa
  • ベストアンサー率57% (34/59)
回答No.3

ほんじゃ回答の補足を引き継ぎます まず、WorksheetFunction の使い方から CountIf に限らず WorksheetFunction の引数は『基本的にセルに書くのと同じ形式』で入力します 例えばSUM  セルだと =SUM(A1:A2) なんて書きますね WorksheetFunction だと WorksheetFunction.Sum(Range("A1:A5"))  です 引数を変数で入れるなら Set MyRange = Range("A1:A5") WorksheetFunction.SUM(MyRange) てな具合 この辺の規則性が判れば、あとは簡単 NO.1の方が言う通り、CountIf の場合 COUNTIF(範囲,検索条件) 範囲 セルの個数を求めるセル範囲を指定します。 検索条件 計算の対象となるセルを定義する条件を、数値、式、または文字列で指定します。式および文字列を指定する場合は、">32"、"Windows" のように、半角の二重引用符 (") で囲む必要があります。 なので、引数が足りません そもそもここはRange範囲を入れるので Range("○:□") の形です 範囲は(gyo1:gyo2)で取ってるつもりのようですが、『:』が文字ではない為、まず構文エラーです つまり Range(gyo1 & ":" & gyo2) となります VB or VBA では、文字は "(ダブルコーテーション)で囲みます また、文字の連結には & を使います  それと、折角No.2の方が .Address としてくれていますが、Range として使用するので、 gyo1 = Cells(row, 1) gyo2 = Cells(row, 2) でOK Range(gyo1 ,gyo2) となります さらに言えば Range(Cells(row, 1),Cells(row, 2)) と使えば済む話なので、行けるのであれば変数に一旦受ける必要も無いかも・・・ もう少しです 次は肝心の検索条件です >数値が入力されていれば数えたい 予想された通り ">0" です これが検索条件となります 完成 Cells(Row, 5).Value = WorksheetFunction.CountIf(Range(gyo1, gyo2), ">0") とまあここまで書いてアレですが、WorksheetFunction は最初の内、実際にセルに =COUNTIF(A1:C1,">0") とか書いてからそれをコピペして、各カンマごとの引数を変数なりに置き換えて行くと混乱しにくいですよ

Trader-Aki
質問者

補足

回答ありがとうございます。^^ アドバイスのとおり、 gyo1 = Cells(row, 1) gyo2 = Cells(row, 2)  と、 Cells(Row, 5).Value = WorksheetFunction.CountIf(Range(gyo1, gyo2), ">0") を構文に取り入れてみました。 しかし、 Cells(Row, 5).Value = WorksheetFunction.CountIf(Range(gyo1, gyo2), ">0")のところで、 「Rangeメソッドは失敗しました。Globalオブジェクト」というエラーが出てしまいます。 原因が分からず、また止まってしまいました。(TT) また、gyo1とgyo2には、セル位置(A2とか)ではなく、セルの数値が代入されていますが、これでカウントイフできるのでしょうか? セル位置を入れて範囲指定するものだと思っていましたので...

  • pu--n
  • ベストアンサー率56% (32/57)
回答No.2

こんにちわ。 要するに、gyo1に Cells(row, 1)、gyo2に Cells(row, 2) のアドレスを取得したいとのことでよろしいのでしたら、以下のようにすれば取得できます。 Dim row As Integer '定義されていると思いますが・・ Dim gyo1 As Variant 'string形式でもOK Dim gyo2 As Variant 'string形式でもOK row = 2 : : gyo1 = Cells(row, 1).Address row = row + 1 '次の行へ : : gyo2 = Cells(row, 2).Address row = row + 1 '次の行へ : : これで解決するようでしたら、ほとんど丸投げに近いので注意してね!。

Trader-Aki
質問者

補足

回答ありがとうございます。 教えて頂いたコードで、問題解決できました。(^^) ↓この件も、初歩的な質問かもしれませんが、アドバイス頂けると嬉しいです。 Cells(row, 5).Value = WorksheetFunction.CountIf(gyo1:gyo2) gyo1からgyo2までの範囲で、数値が記載されているセルの数を数え、 Cells(row,5)に表示させたいのですが、いろいろ試してもエラーが出てしまいます。 よろしくお願いいたします。 丸投げとご指摘を受けて反省しています。 今一度、自己学習に努めたいと思います。

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

選択されているセルが変化しないならSelection.AddRessの返すデータは変化しないように思います AddressはRangeオブジェクトまたは HyperLinkオブジェクトのプロパティです Selectionは Rangeオブジェクトを返すので Selection.Addressといった使い方は出来ます ですが 単に Addressとしても Excelはそんな命令を知りません したがって エラーになるのです COUNTIFは ワークシート関数ですから WorksheetFunction. をつけないといけないでしょう 引数も足りませんよどのような条件でカウントするのかを与えないといけません ユーザー定義の関数として countifを実装しているなら的外れですが

Trader-Aki
質問者

補足

回答ありがとうございます。 gyo1 = Cells(row, 1).Address とする事で問題解決できました。 VBAの基礎がまだ身についていないんだと、改めて実感しましたので、 ネットや書籍で、これから自己学習を高めていこうと思います。 COUNTIFの使い方も理解できていなく、下記コードにも苦戦しています。 Cells(row, 5).Value = WorksheetFunction.CountIf(gyo1:gyo2) gyo1からgyo2範囲の数値をカウントしたいのですが、エラーが出てしまいます。 (数値が入力されていれば数えたいので、条件は>0でいいのでしょうか。) アドバイス頂けたら嬉しいです。 よろしくお願いします。

関連するQ&A

  • VBA 選択された離れたセルの値の取得について

    EXCELのVBAでどうしても前に進めず困っております。 目的としているコードは、離れたセル(複数)をあらかじめCtrlキーで選択状態にしておき、選択されたセルの値のみをVBAが別のセルに並べていくというものです。 以下が私の作ったコードなのですが、思ったとおりの動作をしてくれません。 VBA初心者なもので、おかしな記述がたくさんあると思うのですが、どなたかアドバイスお願いします。 Public Sub xx() Dim SelectArea As String Dim TargetCell As Range Dim a As Integer Dim Row As Integer Dim Column As Integer Dim CNT1 As Integer a = 0 Row = 0 Column = 0 For CNT1 = 1 To 10 Row = Row + 1 SelectArea = Selection.Address Set TargetCell = Range("B3").Cells(Row - 1, Column) If Intersect(Range(SelectArea), TargetCell) Is Nothing Then Else Range("A30").Cells(a, 0) = Range("B3").Cells(Row - 1, Column).Value a = a + 1 End If Next End Sub

  • 空白セルと0値を識別させたい。(VBA)

    すみません、誰か教えていただけますか。 シートの53、54、55行目にそれぞれ値入っています。 それを3行目にビジュアル的に表現させています。 55行目はセルの色で、53行目は数値があり同じ値が 続く部分の合計を出しています。 しかし、下記の記述ですと数値が0(変数D=0)の時に うまくいきません。空白セルと認識されてしまうと思います。 何か、良い方法があれば教えて頂けませんでしょうか。 宜しくお願いします。 Sub 表示() Dim a As Long Dim c As Long Dim D As Long Dim e As String Dim f As String c = 3 For a = 3 To 64 With Worksheets("Sheet1") If .Cells(53, a) <> .Cells(53, a + 1) Then .Range(.Cells(53, c), .Cells(53, a)).Select D = WorksheetFunction.Sum(Selection) e = D f = Selection(1).Offset(1, 0).Value G = Selection(1).Offset(2, 0).Value If D <> 0 Then Selection(1).Offset(-50, 0).Value = f + "//" + e .Range(.Cells(53, c), .Cells(53, a)).Offset(-50, 0).Select Selection.Interior.ColorIndex = G End If If Selection(1).Value = "" Then .Range(.Cells(53, c), .Cells(53, a)).Offset(-50, 0).Select Selection.ClearContents Selection.Interior.ColorIndex = xlNone End If c = a + 1 End If End With Next End Sub

  • EXCEL VBAについて

    EXCEL VBAについて教えてください やりたいことは以下の通りです。 ・全シートJ列1~100行目を検索しアルファベットが含まれるセルが存在すれば 上のセルをコピーする ここまで作ったのですが上手くいきません Sub VBAsample() Dim GYO As Long For GYO = 1 To 100 If Find([a-z], LookAt:=xlPart) Then Cells(GYO, 10).Value = Cells(GYO - 1, 10).Value End If Next GYO End Sub 添削をお願いします

  • Excel VBAについて

    Excel VBAについて VBA初心者ですが、作業で使うファイルを使いやすくしようと思っているのですが行き詰ってしまいました。 是非、知恵をお貸しいただきたいと質問させていただきました。 フォームを使ってデータを打ち込むようにしようと思っています。 日付の列を選択するとフォームが立ち上がり、必要項目を記入するというものです。 日付欄が未記入なら「新規」、記入済みなら「修正」 という風にしたいのですが、うまくいきません・・・ 修正しようと入力しなおしても新規として新しい行に書かれてしまいます。 色々と自分で勉強して下のような書き方をしましたが、何がいけないのでしょうか。 ご指摘おねがいいたしますm(__)m Public Sub KAKIKOMI(GYO As Long) GYO = ActiveCell.Row Load UserForm1 With UserForm1 If ((GYO = 17) Or (Cells(GYO, 3).Value = "")) Then GYO = 17 .hiduke.Text = "" .bunnrui.Text = "" .tantou.Text = "" .gaku.Text = "" .memo.Text = "" Else .hiduke.Text = Cells(GYO, 3).Value .bunnrui.Text = Cells(GYO, 7).Value .tantou.Text = Cells(GYO, 8).Value .gaku.Text = Cells(GYO, 9).Value .memo.Text = Cells(GYO, 11).Value .ComboBox1.Text = Cells(GYO, 5).Value End If g_swOK = 0 .Show If g_swOK <> 1 Then GoTo TOUROKU_EXIT If GYO = 17 Then GYO = 19 Do While Cells(GYO, 1).Value <> "" GYO = GYO + 1 Loop End If ActiveSheet.Unprotect Cells(GYO, 3).Value = Trim$(.hiduke.Text) Cells(GYO, 7).Value = Trim$(.bunnrui.Text) Cells(GYO, 8).Value = Trim$(.tantou.Text) Cells(GYO, 9).Value = Trim$(.gaku.Text) Cells(GYO, 11).Value = Trim$(.memo.Text) ActiveSheet.Protect End With End Sub ちなみに、17行目が見出しで、3列目が日付欄です。 よろしくお願いします。

  • エクセルVBAについて質問です

    お世話になります。 早速ですが、下記の構文を作成しましたが、Activecell.Rowの部分で悪さをし 上手く動きません。 行いたかった事としては、Functionにて関数を手作りしようと試みたのですが、 結局は壁にぶちあたってしまったって所です。。。 内容としては、エクセルが手動計算だった場合は、一回りで動作が終了するので 問題なく想定の値が叩き出されますが、自動計算にした途端に「別セルに入れた 計算式まで、Activecell.Rowに引きずられて計算をし、別の値に変わってしまう」 現象となってしまいました。。。(説明下手で済みません) Public Function Shotoku(houshu As Long) Dim ACcel As Variant Dim FR As Range With Worksheets("所得税月額表(平成24年分)") ACcel = houshu If ACcel < 88000 Then Shotoku = 0 Exit Function End If For Each FR In .Range("C13:C347") If ACcel < FR Then If Cells(ActiveCell.Row, 51) = 0 Then       ←問題の個所です Shotoku = .Cells(FR.Row, 4) ElseIf Cells(ActiveCell.Row, 51) = 1 Then    ←問題の個所です Shotoku = .Cells(FR.Row, 5) ElseIf Cells(ActiveCell.Row, 51) = 2 Then    ←問題の個所です Shotoku = .Cells(FR.Row, 6) ElseIf Cells(ActiveCell.Row, 51) = 3 Then    ←問題の個所です Shotoku = .Cells(FR.Row, 7) ElseIf Cells(ActiveCell.Row, 51) = 4 Then    ←問題の個所です Shotoku = .Cells(FR.Row, 8) ElseIf Cells(ActiveCell.Row, 51) = 5 Then    ←問題の個所です Shotoku = .Cells(FR.Row, 9) ElseIf Cells(ActiveCell.Row, 51) = 6 Then    ←問題の個所です Shotoku = .Cells(FR.Row, 10) ElseIf Cells(ActiveCell.Row, 51) = 7 Then    ←問題の個所です Shotoku = .Cells(FR.Row, 11) End If Exit For End If Next End With End Function 計算式を当て込んで、例えば2行目のIF文の条件に引っかかった場合、他の セルまでその行を読んでしまうので、条件が変わってしまう事態になってます。 イメージではActivecell.Rowがダメなんだと思いますが、これ以外のセル番地の 取得方法が分からなくって><; どなたかお助け願います!!!

  • Excel VBA スケジュールマクロ最適化

    現在下記の様なスケジュール表を作成しています。 ・セル(14,3)から下方は"タスク"列 ・セル(14,5)から下方は"開始日"列 ・セル(14,7)から下方は"終了日"列 ・セル(14,8)から下方は"重要度"列 ・セル(11,11)から右側へ日付が連番で入っている ・開始日と終了日を入れると自動的に変更された行を取得し、開始/終了日の範囲でセルの塗り潰しを実行 ・重要度で色を変更し、"M"を入れると★マーク表示し、その右側へタスク名表示 3つ質問があります。 (1)現在、セルの塗り潰しを行うのに下記の様に設定しているのですが、日付を入れてからセルの塗り潰しがされるまで若干時間がかかるのですが、何か他に良い方法は無いでしょうか? (2)あと、終了日の最大値を取得して、セル(11,11)から右側へ伸びている日付行を自動調整したいのですが、方法が分からなくて困っています。 (3)VBA初心者の為、色々調べながら作っているのですが、継ぎはぎだらけなので、改善したらよいポイントなどがあれば教えて頂けると助かります。 ================================================================ Option Explicit Private Sub Worksheet_Change(ByVal Target As Range) Dim Gyo As Long Dim COL As Long Dim c As Integer Dim l As Integer Dim n As Integer c = 11 l = 11 Gyo = Target.Row ' 変更した行を取得 If Gyo <= 13 Then Exit Sub ' 1~13なら無視 COL = Target.Column ' 変更した列を取得 If ((COL <= 4) Or (COL >= 9)) Then Exit Sub '開始日、終了日以外は無視 ' 計算式セット自体でもイベントが発生するのでイベントを抑制 Application.EnableEvents = False '入力した条件により、セルの塗りつぶし範囲を取得 If Cells(Gyo, 5) <= Cells(11, c) Then Do Until Cells(Gyo, 5) >= Cells(11, c) c = c + 1 Loop ElseIf Cells(Gyo, 5) >= Cells(11, c) Then Do Until Cells(Gyo, 5) <= Cells(11, c) c = c + 1 Loop End If If Cells(Gyo, 7) <= Cells(11, l) Then Do Until Cells(Gyo, 7) >= Cells(11, l) l = l + 1 Loop ElseIf Cells(Gyo, 7) >= Cells(11, l) Then Do Until Cells(Gyo, 7) <= Cells(11, l) l = l + 1 Loop End If 'セルの色をクリア Rows(Gyo).Interior.ColorIndex = xlNone 'セルの塗りつぶし範囲に色を設定 If Cells(Gyo, 8) = 1 Then For n = c To l Cells(Gyo, n).Clear Cells(Gyo, n).Interior.ColorIndex = 3 Next n ElseIf Cells(Gyo, 8) = 2 Then For n = c To l Cells(Gyo, n).Clear Cells(Gyo, n).Interior.ColorIndex = 26 Next n ElseIf Cells(Gyo, 8) = 3 Then For n = c To l Cells(Gyo, n).Clear Cells(Gyo, n).Interior.ColorIndex = 5 Next n ElseIf Cells(Gyo, 8) = "M" Then Cells(Gyo, c) = "★" Cells(Gyo, 3).Copy Cells(Gyo, c + 1).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False Application.CutCopyMode = False Cells(Gyo, 8).Select Else For n = c To l Cells(Gyo, n).Clear Cells(Gyo, n).Interior.ColorIndex = 10 Next n End If 'イベントを再開 Application.EnableEvents = True End Sub ============================================================

  • エクセル2003 VBAでセル移動

    いつもお世話になります。 Private Sub Worksheet_SelectionChange(ByVal Target As Range) If Target.Row > 9 Then If Target.Column = 3 Then Cells(Target.Row, 4).Select ElseIf Target.Column > 5 Then Cells(Target.Row + 1, 1).Select End If End If End Sub これで、B列からC列を飛ばしてD列にセル移動して取りあえずの目的は達成しているのですが、 D列からB列には方向キー移動してくれません。Target.Columnが3になるんで当たり前なんですが・・・ B列の入力ミスがあるときマウスで移動させるか、A列まで戻ってから方向キーで上に上がるかです。 何かいい方法ありませんでしょうか。D列から方向キーで戻るときも、出来ればC列を飛ばしてほしいです。 よろしくお願いします。

  • EXCEL VBA 取得したセルの列の最終行

    お客さんからいただいたEXCELフォーマットに沿って、集計ツールを作成していますが 下記でつまってしまいました。 Wb.Worksheets("Sheet1").Cells.Find("実施日").Select Sel_Col = Selection.Column Last_Row = Wb.Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row ※1 For i = Last_Row To 2 Step -1 If Wb.Worksheets("Sheet1").Cells(Sel_Col, i).Value = Day Then ※2 If Wb.Worksheets("Sheet1").Cells(Sel_Col, i).Offset(-5).Value = "A" Then A_count = A_count + 1 ElseIf Wb.Worksheets("Sheet1").Cells(Sel_Col, i).Offset(-5).Value = "B" Then B_count = B_count + 1 ElseIf Wb.Worksheets("Sheet1").Cells(Sel_Col, i).Offset(-5).Value = "C" Then C_count = C_count + 1 End If Else End If Next i まず※1の箇所ですが、Sheet1の実施日と入力されているセルの列番号を取得して その列の最終行を取得したいのですが、上記作成したものですと入力されている列全部の 中での最終行が取得されてしまいます。 この場合、Sel_Col をどのように使えばよろしいでしょうか? 次に※2ですが、※1で取得した列の最終行から1つずつ上に上がりながら 日付が今日であれば、そのセルから5つ左のセルのA、B、Cいずれかを カウントするという造りにしたいと思っています。 実行すると1004エラーでアプリケーション定義、オブジェクト定義のエラーと 出てしまいます。 Wbはset Wbとして開いたブックを定義しています。 DayはDay = Dateで今日の日付を取得しています。 独学で無茶苦茶なコードですが、 どなたか詳しい方、ご教示お願いいたします。

  • エクセルのVBAの記述について

    VBAの記述についてなのですが、 Sub filter() Dim gyo As Long Dim ws1 As Worksheet Dim ws2 As Worksheet Dim ws3 As Worksheet Set ws1 = Worksheets("データ") Set ws2 = Worksheets("チーム") Application.ScreenUpdating = False ws2.Range("A4:BH30").Clear gyo = ws1.Range("A65536").End(xlUp).Row ws1.Activate With ws1.Range(Cells(4, 1), Cells(gyo, 6)) .AutoFilter Field:=1, Criteria1:="A" .SpecialCells(xlCellTypeVisible).Copy ws2.Range("A4") Selection.AutoFilter End With Application.ScreenUpdating = True End Sub ならプログラムははしるのですが、 14行目を .SpecialCells(xlCellTypeVisible).Copy ws2.Range(Cells(4, 1)) だと 「実行時エラー 1004 Rangeメソッドは失敗しました Worksheet オブジェクト」 とでるのですが、出来ないのでしょうか? Cells(4, 1)の1のところを変数にして変えていきたいのですが、よい方法はありますか。 よろしくお願いいたします。

  • エクセルVBA 対比表を作りたいです。

    お世話になります。混乱を極めてしまったので、質問させて頂きます。 下記の様なリストがあります。 A列  B列 No  相手 1   1 1   2 1   3 1   5 2   1 2   2 3   2 3   3 3   4 ・  ・ ・  ・ ・ 以下、数百まであります。 上記で 「1-2」と「2-1」はありますが、「1-3」はあるけど「3-1」がありません。 (その他「1-5」無いなどです。上記は一例としてます。) この場合「1-3」の部分の「1」を「0」などに置き換えたいのですが、下記コードを 書きましたが、上手く目的の結果にたどり着けない状態になっております。 (同じ部分を検索しているだけになってしまっていて。。。) 下記はユーザーフォームからのコードになりますので、ListBoxの記載ありますが、 選択されているListBoxの値で非一致を探すって形にしようとしております。 For Each KRR In Range("A2:A" & Cells(Rows.Count, 1).End(xlUp).Row) If KRR = ListBox1.List(ListBox1.ListIndex, 0) Then SDF = Cells(KRR.Row, 2) For Each SRR In Range("A2:A" & Cells(Rows.Count, 1).End(xlUp).Row) If Cells(SRR.Row, 1) = SDF Then SSDF = 1 End If Next If SSDF <> 1 Then Cells(KRR.Row, 1) = 0 End If SSDF = 0 End If Next 要するにA列とB列を反対にした状態で、一致する値が無い場合は、対象CellのA列に「0」を 代入したいって事を考えております。 完全に混乱してしまっているので、お助け下さい。。。

専門家に質問してみよう