2017-03-13 11 views
2

VBAを初めて使用しました。基本的なコーディングを開始しています。VBAを使用して値の範囲を検索し、値の列を変数として返します。

現在の最終目標は、2つのデータ検証済みセルの入力に基づいてテーブル内のセルをゼロにすることです。

私は現在、私がやろうとしていることをうまく実装するためのシートを持っていますが、コードは長く、Find関数を使用して効率化できると確信しています。私はこの回避策を実装する前に数時間Findを実装しようとしました。

ユーザーは、セルB4の有効なリストを通じて現在の予測月を選択します。次に、セルB5で「はい/いいえ」を選択して、希望のセルを「ゼロにする」ことを選択できます。月はB7:M7からレイアウトされています。私の最初の目標は、VBAにB4から選択された月をとり、B7:M7でその月を見つけ、その列を返し、列データを使用して行15に移動し、そのセルをゼロにすることでした。しかし、コンパイルエラーを引き起こすことなくfind関数にこれを記述する適切な方法を見つけることができませんでした。以下は

私は合理化することが可能と考えている現在のコードです:

Private Sub Worksheet_Change_B(ByVal Target As Range) 
If Target.Address(False, False) = "B5" Then 
    If Range("B5").Value = "Yes" Then 
     If Range("B4").Value = "Oct" Then 
      Range("B15").Value = "0" 
     ElseIf Range("B4").Value = "Nov" Then 
      Range("C15").Value = "0" 
     ElseIf Range("B4").Value = "Dec" Then 
      Range("D15").Value = "0" 
     ElseIf Range("B4").Value = "Jan" Then 
      Range("E15").Value = "0" 
     ElseIf Range("B4").Value = "Feb" Then 
      Range("F15").Value = "0" 
     ElseIf Range("B4").Value = "Mar" Then 
      Range("G15").Value = "0" 
     ElseIf Range("B4").Value = "Apr" Then 
      Range("H15").Value = "0" 
     ElseIf Range("B4").Value = "May" Then 
      Range("I15").Value = "0" 
     ElseIf Range("B4").Value = "Jun" Then 
      Range("J15").Value = "0" 
     ElseIf Range("B4").Value = "Jul" Then 
      Range("K15").Value = "0" 
     ElseIf Range("B4").Value = "Aug" Then 
      Range("L15").Value = "0" 
     ElseIf Range("B4").Value = "Sep" Then 
      Range("M15").Value = "0" 
     End If 
    ElseIf Range("B5").Value = "No" Then 
     If Range("B4").Value = "Oct" Then 
      Range("B15").Value = Range("B35").Value 
     ElseIf Range("B4").Value = "Nov" Then 
      Range("C15").Value = Range("C35").Value 
     ElseIf Range("B4").Value = "Dec" Then 
      Range("D15").Value = Range("D35").Value 
     ElseIf Range("B4").Value = "Jan" Then 
      Range("E15").Value = Range("E35").Value 
     ElseIf Range("B4").Value = "Feb" Then 
      Range("F15").Value = Range("F35").Value 
     ElseIf Range("B4").Value = "Mar" Then 
      Range("G15").Value = Range("G35").Value 
     ElseIf Range("B4").Value = "Apr" Then 
      Range("H15").Value = Range("H35").Value 
     ElseIf Range("B4").Value = "May" Then 
      Range("I15").Value = Range("I35").Value 
     ElseIf Range("B4").Value = "Jun" Then 
      Range("J15").Value = Range("J35").Value 
     ElseIf Range("B4").Value = "Jul" Then 
      Range("K15").Value = Range("K35").Value 
     ElseIf Range("B4").Value = "Aug" Then 
      Range("L15").Value = Range("L35").Value 
     ElseIf Range("B4").Value = "Sep" Then 
      Range("M15").Value = Range("M35").Value 
     End If 
    End If 
End If 

End Sub 

私はもともと検索機能を考えていた何のように行ってきましたが、私はそれが正常にコンパイルすることができませんでした。

Sub Test() 

Dim rFind As Range 

If Target.Address(False, False) = "B5" Then 
    If Range("B5").Value = "Yes" Then 'If the user wants to zero out the cell on row 15 
     With Range("B7:M7") 'Range of Months 
      Set rFind = .Find(What:=("B4"), LookAt:=xlWhole, MatchCase:=False, SearchFormat:=False) 
       Range("rFind.Column,15").Value = "0" 'Set Value of cell in row 15 of referenced column to zero 
     End With 
    If Range("B5").Value = "No" Then 'If the user doesn't want to zero out cell on row 15 
     With Range("B7:M7") 'Range of Months 
      Set rFind = .Find(What:=("B4"), LookAt:=xlWhole, MatchCase:=False, SearchFormat:=False) 
       Range("rFind.Column,15").Value = Range("rFind.Column,35").Value 'Pulls in Previous Value 
     End With 
    End If 
End Sub 

私は進んでいますか?変更したいセルの住所の月の列をどのように参照できますか?

答えて

3

構文は、これらの文に間違っている:

Range("rFind.Column,15").Value = 0

Range("rFind.Column,15").Value = Range("rFind.Column,35").Value

は次のようになります。

Cells(15, rFind.Column).Value = 0 

Cells(15, rFind.Column).Value = Cells(35, rFind.Column).Value 

ここでは別の構文エラー:

What:=("B4"), ...

完全性については

What:=Range("B4").Value, ... 

する必要があり、ここにあなたがあなたの最初のバージョンを簡素化することができます方法は次のとおりです。

Private Sub Worksheet_Change_B(ByVal Target As Range) 

    ' we're only interested when cell B5 changes 
    If Target.address <> "$B$5" Then Exit Sub 

    ' First we will get the month's number from its name. We use the Month 
    ' method of VBA but it needs a date. so we append a 1 to the month (i.e. Sep 1) 
    Dim col As Long 
    col = Month(Range("B4").value & " 1") 

    ' Getting the column. Since First cell is in column 2 (B) we start at column 2 
    ' Month 10 (Oct) comes first so we count from that using modulo 
    col = 2 + ((col + 2) Mod 12) ' since you start with Oct. at column B 

    ' Finally we set the value at row 15 according to cell B5 (Target) 
    ' We can shorten the If statement using IIF(condition, trueValue, falseValue) 
    Cells(15, col).value = IIf(Target.value = "Yes", 0, Cells(35, col).value) 

End Sub 
+0

私は現時点では編集できませんが、誤ったバッククォートが表示されています - セル(15、rFind.Column)。値= 0' –

+0

ありがとうございました!私はその点でそれについて行くことを考えなかった。 Dim Col as Long、それから、次のようなときに何が起こっているのか少し説明できますか?ちょうど一緒に従おうとしている。 –

+0

@ D.Horowitz確かに、私はより多くのコメントを追加します。 –

0

私はあなたの月のシーケンスについてあまりよく分かりません。あなたは試みることができる :

Private Sub Worksheet_Change_B(ByVal Target As Range) 
    If Target.address <> "$B$5" Then Exit Sub 
    With Range("B7:M7").Find(What:=Range("B4").Value, lookin:=xlValues, lookAt:=xlWhole) 
     Cells(15, .Column).value = IIf(Target.value = "Yes", 0, Cells(35, .Column).value) 
    End With 
End Sub 
+0

@ D.Horowitz、このコードを試しましたか? – user3598756

2

のSelect Caseステートメントといくつかの基本的な数学のカップルは、あなたの条件のすべての迅速な作業を行います。パターンが見つかると、いくつかの日付関数があなたのオフセットに合わせて調整された序数月を達成します。

Option Explicit 

Private Sub Worksheet_Change(ByVal Target As Range) 

    If Target.Address(False, False) = "B5" Then 
     On Error GoTo Safe_exit 
     Application.EnableEvents = False 
     If LCase(Range("B5").Value2) = "yes" Then 
      Select Case LCase(Range("B4").Value2) 
       Case "jan", "feb", "mar", "apr", "jun ", "jul", "aug", "sep", "oct", "nov", "dec" 
        Cells(15, Month(DateSerial(2017, Month(DateValue("1-" & Range("B4").Value2)) + 3, 1)) + 1) = 0 
       Case Else 
        'do nothing 
      End Select 
     ElseIf LCase(Range("B5").Value2) = "no" Then 
      Select Case LCase(Range("B4").Value2) 
       Case "jan", "feb", "mar", "apr", "jun ", "jul", "aug", "sep", "oct", "nov", "dec" 
        Cells(15, Month(DateSerial(2017, Month(DateValue("1-" & Range("B4").Value2)) + 3, 1)) + 1) = _ 
         Cells(35, Month(DateSerial(2017, Month(DateValue("1-" & Range("B4").Value2)) + 3, 1)) + 1).Value 
       Case Else 
        'do nothing 
      End Select 
     End If 
    End If 
Safe_exit: 
    Application.EnableEvents = True 
End Sub 

親ワークシートの適格性について心配する必要はありません。あなたは、ワークシートのコードシートのプライベートサブにいます。非修飾範囲またはセル参照は、コードシートのワークシートに属するものとみなされます(詳細はIs the . in .Range necessary when defined by .Cells?を参照)。

+0

ありがとうございました!私はVBAでこの能力を知らなかったし、プロジェクトの他の要素についても私を助けてくれるだろう。 –

関連する問題