• ベストアンサー

エクセルVBA教えて下さい

エクセルの表で -AB C D E F 1年月--1801 2------ 3------ 4------ (-)は空欄でセルE1=18、F1=1とします。 コントロールボックスをつかって Private Sub Command登録_Click() d1 = Range("A65536").End(xlUp).Row d2 = Range("B65536").End(xlUp).Row Cells(d1 + 1, 1) = Range("E1").Value Cells(d2 + 1, 2) = Range("F1").Value End Sub とすると、登録コマンドを押すたびに次々セルA,Bに同じ数値が登録されるのですが、一回登録した数値を2度登録できないようにする方法はありませんか?  要は、この表だと18と1という条件では、2度登録できないようにしたいのです。よろしくお願いします。

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

  • ベストアンサー
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.1

こんばんは。 コードの中だけです。 配列数式で処理することを考えてみました。他の方法ですと、遅いし面倒になるはずです。以下をステップモードで研究してみてください。  Dim d1 As Long   Dim d2 As Long   Dim ret As Variant   Dim FindValue As String   Dim TotalAddress As String   If Range("E1").Value = "" Or Range("F1").Value = "" Then    MsgBox "該当する場所にデータが入っていません。", vbCritical    Exit Sub   End If   d1 = Range("A65536").End(xlUp).Offset(1).Row   d2 = Range("B65536").End(xlUp).Offset(1).Row   FindValue = """" & Range("E1").Value & Range("F1").Value & """"   TotalAddress = Range("A1").Resize(d1).Address & "&" & Range("B1").Resize(d1).Address   '配列数式による検索   ret = Evaluate("MATCH(" & FindValue & "," & TotalAddress & ",0)")   If IsError(ret) Then     Cells(d1, 1) = Range("E1").Value     Cells(d2, 2) = Range("F1").Value    Else     MsgBox "既に同じ組み合せがあります。", vbInformation   End If

19760101
質問者

補足

ありがとうございます。大変役に立ちましたし、応用することができました。感謝します。 ちなみに私はVBA初心者なのですが、 FindValue = """" & Range("E1").Value & Range("F1").Value & """"   TotalAddress = Range("A1").Resize(d1).Address & "&" & Range("B1").Resize(d1).Address   '配列数式による検索   ret = Evaluate("MATCH(" & FindValue & "," & TotalAddress & ",0)")   If IsError(ret) Then あたりの意味が知識不足で読めません。できればこの意味を教えていただきたいのですが・・・

その他の回答 (2)

  • taocat
  • ベストアンサー率61% (191/310)
回答No.3

こんにちは。 既に解決してるようですが、VBA初心者ということなので何をしているか見た目で分かるForなどで回す方法もありかも知れませんね。 --------------------------------------- Private Sub Command登録_Click()  Dim Ari   As Integer  Dim LastRow As Long  Dim R    As Long  For R = 2 To Range("A65536").End(xlUp).Row    If Cells(R, "A").Value = Range("E1").Value _      And Cells(R, "B").Value = Range("F1").Value Then        Ari = 1        Exit For    End If  Next R  If Ari <> 1 Then    LastRow = Range("A65536").End(xlUp).Row    Cells(LastRow + 1, "A").Value = Range("E1").Value    Cells(LastRow + 1, "B").Value = Range("F1").Value  End If End Sub ---------------------------------------------- それから質問のコードで d1 = Range("A65536").End(xlUp).Row d2 = Range("B65536").End(xlUp).Row このようにA列B列別々に最終行を求めてますがこれどちらか一方でいいのではありませんか? 回答ではA列最終行のみで処理しています。 以上です。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.2

19760101様 こんばんは。Wendy02です。 >意味が知識不足で読めません。できればこの意味を教えていただきたいのですが・・・ 知識不足ということはないと思います。配列数式が得意な人なら、いつかは気が付く方法です。仮に、通常の式に戻しても、まだヘンな内容のはずです。 ワークシートで、 =MATCH(E1 & F1,A1:A10&B1:B10,0) 『ShiftとCtrlを押しながらEnterキー』 としてみると、もしも、検索値があれば、範囲内にあれば、ヒットしますし、そうでなければ、エラーが出ます。それを応用したものです。VBAには、もともと、配列数式 FormulaArray とは別に、一般式についてはありません。それを、Evaluate を使って、値を取り出すことが可能であることを応用したものです。 VBAコードとしては、もう少しきれいな方法はあるものの、この方法は、便利で検索スピードも速いので、今回、使うことにしました。

関連するQ&A