2012-03-03 11 views
0

割り当てられた開発者に基づいて特定の料金を計算してストーリー・タスクのコストを計算できるようにマクロをまとめました。私は2番目のシートにレートテーブルを持っています。私は、マクロが(行2)に設定されているセルの結果を得ることができますが、すべての行で実行する必要があります。私は一般的な範囲を設定しなければならないが、わからない。すべての行で実行する範囲宣言をどのように変更する必要がありますか?私はあなたが理由を理解するために十分であることを望む説明してあなたのコードを書き換えているワークシートのすべての入力行にマクロを実行する範囲を設定する

Sub GetCost() 
    Range("D2").Select 
    ' Set Do loop to stop when an empty cell is reached. 
    Do Until IsEmpty(ActiveCell) 
    Dim Estimate As Integer, Assignee As String, RodRate As Integer, GarthRate As Integer, DerekRate As Integer, TotalCost As Integer 

    Estimate = ThisWorkbook.Worksheets("Sheet1").Range("D2").Value 
    Assignee = ThisWorkbook.Worksheets("Sheet1").Range("E2").Value 
    RodRate = ThisWorkbook.Worksheets("Sheet2").Range("B2").Value 
    GarthRate = ThisWorkbook.Worksheets("Sheet2").Range("B3").Value 
    DerekRate = ThisWorkbook.Worksheets("Sheet2").Range("B4").Value 

    If Assignee = "Rod" Then 
     TotalCost = Estimate * RodRate 
    ElseIf Assignee = "Garth" Then 
     TotalCost = Estimate * GarthRate 
    ElseIf Assignee = "Derek" Then 
     TotalCost = Estimate * DerekRate 
    Else 
     TotalCost = "0" 

    End If 

    ThisWorkbook.Worksheets("Sheet1").Range("F2").Formula = TotalCost 
    ActiveCell.Offset(1, 0).Select 
    Loop 
End Sub 

答えて

3

:ここ
はコードです。私が言うことができるものがずっとあります。私はこれがあまりにも少なすぎるとあまりにも多くの間のバランスが良いことを願っています

しかし、いくつかの優れたプロジェクト管理ツールがあることを指摘しておきます。私はこれがあなたの時間をうまく利用しているとは思わない。 32ビットコンピュータ上で

ランダムな点

、ロング整数よりも優れています。

ループ内に変数を宣言しないでください。サブルーチン内で宣言された変数のスコープは、サブルーチンの であり、サブルーチンの先頭に宣言します。

すべての変数を単一のDimステートメントで宣言できますが、2つ以上の変数間に実際の関連がない限り、混乱することがあります。私は、これらの変数が関連付けられているので、

Dim RodRate As Long, GarthRate As Long, DerekRate As Long 

があります。しかし、このアプローチの問題は、あなたのプロジェクトに参加するときにMaryRateJohnRateAngelaRateを追加する必要があることです。

あなたは配列必要があります:ロッド用PersonRate(1) =レート、ガースとデレクのためPersonRate(3) =レートについてPersonRate(2) =レート

Dim PersonRate(1 To 3) As Long 

を。

しかし、これはほとんど優れていません。あなたは成長できるテーブルが必要です。だから、今日:

Name Rate 
    Rod 20 
    Garth 25 
    Derek 15 

次の週:

これにより
Name Rate 
    Rod 20 
    Garth 25 
    Derek 15 
    Mary 30 

、あなたはその後、彼らの率のために全体で見て、あなたが自分の名前を見つけるまで、表を下に実行し、譲受人の名前を拾います。

このような表がSheet2にあるとします。 Sheet2に戻っても、テーブルを配列にロードする方が良いでしょう。

我々は持っている可能性があり:

Dim PersonName() As String 
Dim PersonRate() As Long 

のでPersonRate(2)PersonName(2)のレートを提供します。

私の最初の配列宣言では、私はPersonRate(1 To 3)と書いています。今回は、大括弧が空です。PersonRate(1 To 3)では、配列の3つのエントリが正確に必要であり、これは変更できないと言っています。 PersonRate()では、配列が欲しいと言っていますが、実行時までのエントリ数はわかりません。

PersonName()PersonRate()という2つの配列を持つことができました。これは私が行ったことです。これは分かりやすいアプローチですが、私はそれが最良のアプローチだとは思わないのです。私は構造が好きです。このマクロが動作していて、次のルックアップを開始する前に、構造体のVBA名であるUser Typesを参照してください。

は考えてみましょう:

With Sheets("Sheet2") 
    RowMax = .Cells(Rows.Count, "A").End(xlUp).Row 
    End With 

ここで説明するがたくさんあります。

Cellsアクティブブック内のセルにアドレスしたいということです。 .Cellsは、Withステートメントで識別されたシート内のセルをアドレス指定することを意味します。つまり、内容を見るためにSheet1またはSheet2を選択する必要はありません。ワークシートを選択するのが遅く、コードが理解しにくくなる傾向があります。

.Cells(Row, Column)は細胞を識別する。行は数字である必要がありますが、列は数値または列コードにすることができます。A = 1、B = 2、Z = 26、AA = 27など

Rows.Countバージョンのシートの行数を返しますあなたが使用しているExcelの。したがって、.Cells(Rows.Count, "A")は、列「A」の底を識別する。

End(xlUp)は、クリックするとVBAに相当します。Ctrl + UpArrowCtrl + Arrowでおなじみの方は、これらの4つのコントロールを使用することをおすすめします。これらのコントロールは、長方形のテーブルを使用するとわかりやすい結果になります。しかし、空のセルがあると、結果が奇妙になる可能性があります。

これをまとめる:.Cells(Rows.Count, "A").End(xlUp).Rowは、列Aの下部で開始し、値を持つセルにヒットしてその行番号を返すまで上がることを意味します。これにより、Rateテーブルの最後の行にRowMaxが設定されます。 Mary 5の名前とレートで行5を追加すると、このコードは自動的に調整されます。

改訂コード

これは、あなたが始めるのに十分でなければなりません。プログラミングの楽しさへようこそ。

' * Require all variables to be declared which means a misspelt name 
' is not taken as an implicit declaration 
Option Explicit 

Sub GetCost() 

    Dim Estimate As Integer 
    Dim Assignee As String 
    Dim TotalCost As Integer 

    Dim PersonName() As String 
    Dim PersonRate() As String 
    Dim InxPerson As Long 

    Dim RowCrnt As Long 
    Dim RowMax As Long 

    ' You can declare constants and use them in place of literals. 
    ' You will see why later. I could have made these strings and 
    ' used "A", "B", "D", "E" and "F" as the values. Change if that 
    ' is easier for you. 
    Const ColS2Name As Long = 1 
    Const ColS2Rate As Long = 2 
    Const ColS1Estimate As Long = 4 
    Const ColS1Assignee As Long = 5 
    Const ColS1Total As Long = 6 

    ' Before doing anything else we must load PersonName and PersonRate from 
    ' Sheet2. I assume the structure of Sheet2 is: 

    '  A  B 
    ' 1 Name Rate 
    ' 2 Rod 20 
    ' 3 Garth 25 
    ' 4 Derek 15 

    With Sheets("Sheet2") 

    RowMax = .Cells(Rows.Count, ColS2Name).End(xlUp).Row 

    ' I now know how big I want the the name and rate arrays to be 
    ReDim PersonName(1 To RowMax - 1) 
    ReDim PersonRate(1 To RowMax - 1) 

    ' Load these arrays 
    For RowCrnt = 2 To RowMax 
     ' I could have used 1 and 2 or "A" and "B" for the column 
     ' but this is easier to understand particularly if you come 
     ' back to this macro in six month's time. 
     PersonName(RowCrnt - 1) = .Cells(RowCrnt, ColS2Name).Value 
     PersonRate(RowCrnt - 1) = .Cells(RowCrnt, ColS2Rate).Value 
    Next 
    End With 

    With Sheets("Sheet1") 

    ' I am using the same variable for rows in sheets Sheet1 and Sheet2. 
    ' This is OK because I never look at Sheet1 and Sheet2 at the same time. 
    RowCrnt = 2 

    Do Until IsEmpty(.Cells(RowCrnt, ColS1Estimate)) 
     Estimate = .Cells(RowCrnt, ColS1Estimate).Value 
     Assignee = .Cells(RowCrnt, ColS1Assignee).Value 
     .Cells(RowCrnt, ColS1Total).Value = 0 
     ' Locate the Assignee in the PersonName array and 
     ' extract the matching rate 
     For InxPerson = 1 To UBound(PersonName) 
     If PersonName(InxPerson) = Assignee Then 
      .Cells(RowCrnt, ColS1Total).Value = Estimate * PersonRate(InxPerson) 
      Exit For 
     End If 
     Next 
     RowCrnt = RowCrnt + 1 
    Loop 
    End With 

End Sub 
+0

トニー、情報と書き直しありがとう。私はこのことを私が欲するものにする方法の説明に本当に感謝しています。私はそれを勉強し、それがどのようにしているのかを学び、そこから進んでいくでしょう! – Stoney

1

トニーの答えは、プログラミングの優れた解説であり、非常によく書かれているので、私は+1しました。

=D2*(vlookup(E2,'sheet2'!A:B,2,FALSE)) 

が列を下にコピーした:それは式に比べて非常に遅いしかしない限り、私は欠けている何かのコードは常に私が何かのように、簡単な検索で十分だろうと思っているだろう、Excelで最後でなければなりません

+0

+1に感謝します。私は数式がストーニーの直ぐ問題を解決することに同意しますが、これはもっと複雑なものに向かう第一歩だと思いました。 –

+0

カイル、そうです。これは私にとって概念の証明であり、私が望むものをプログラムできるかどうかを確認する挑戦です。私はまた、それがどのように機能するかを理解するために取り組んでいます... – Stoney

関連する問題