2011-10-20 13 views
1

マクロコードを使用して作業することを試みたこのワークブックがあります。そして私はそれに助けをしましたが、誰も私が何をしているのか理解していないようです。これは、弊社の各ユーザーが受け取った作業服の量を追跡して保持するために使用されるワークブックです。 https://skydrive.live.com/view.aspx?cid=5D018DB0458F03ED&resid=5D018DB0458F03ED%21163Excel VBA - 範囲と配列を比較するための支援

  • 概要
  • ユーザー
  • 記事

一般的な考え方は、私がデータからピボットテーブルを作成するというものであった:だから、基本的に、私はこのワークブックの3枚を持っています要約シート。しかし、私はVBAコードを使用してワークブックを動的にしたい。だから私はここでそれぞれのシートを通過します。

ユーザー:このワークブックには1つの列(A)が含まれ、A1は「名前」と呼ばれ、その下の各行には当社の各ユーザーが含まれます。

記事:このブックには2つの列があり、A1は記事の名前(ズボンなど)で、もう1つはそのアイテムの価格です。

要約:これは難しい部分です。このシートは他の2枚のシートのデータを反映している必要がありますが、各ユーザーが受け取った各項目のの数も、個を記録しておく必要があります。このデータを要約シートの列Dに保存します。だから、ユーザーシートの各名前は、記事シートに項目がある回数だけ繰り返す必要があります。記事シートに10項目ある場合は、その名前を10回繰り返す必要があります。そうすれば、ユーザーが受け取った各アイテムの数がどれくらいあるかを知ることができます。

だから、トリッキーな部分は、ユーザーと記事のシートから実際にコンテンツをミラーリングすることですが、Dのデータをサマリーシートに保存します。また、ユーザーシートから行を削除した場合、そのユーザーは、登録された各項目の量を含めて、要約シートから完全に削除する必要があることにも留意してください。また、記事シートにアイテムを追加すると、そのアイテムを要約シートの各ユーザーに追加する必要があります。

誰かが私を助けてくれたマクロコードがありますが、何が起こっているのか分かりません。私は配列やループでは頑丈ではありません。そして、これは私が今それを学ぶ可能性を見ているので、私が今学んでいることです。

しかし私はすべてのシートを自分の範囲で収集し、すべてのデータを保存する必要があることを知ります。次に、ユーザ範囲がサマリー範囲と比較され、ユーザがその範囲内に存在するかどうかを確認する必要があります。そうであれば、記事範囲からデータを更新し、ColumnDの金額を保持してください。要約シートにない場合は追加してください。同じことが各項目にも適用されます。

しかし、ユーザーを誤って入力しても、そのユーザーの金額を追加するまでユーザーが入力しないとどうなりますか?ユーザーシートに戻ってユーザーの名前を変更すると、前に追加したすべてのデータが失われますか?あるいは、ユーザーの名前を変更することも可能ですか?その場合は、WindowsのCIDによく似た、ユーザーごとにいくつかの種類のIDが必要になるでしょうか?これはすべてあまりにも過剰なことですか?時間があれば、それはもっと価値のあるものになる。私は本当にここにいくつかの助けをいただければと思います:)

Public Sub NewCollect() 
' Declare variables 
Dim shtUsers, shtmyArticles, shtmySummary, shtmyAmount As Worksheet 
Dim arrUsers, arrarticles, arramount, arrsummary As Long 

' Set worksheets 
Set shtUsers = Sheets("Brukere") 
Set shtArticles = Sheets("Artikler") 
Set shtSummary = Sheets("Oppsummering") 
Set shtAmount = Sheets("Antall") 

' Get range from shtUsers 
With shtUsers 
    If Not .Range("A2") = "" Then 
     arrUsers = .Range("A2", .Cells(Rows.Count, "A").End(xlUp)).Resize(, 2) 
    End If 
End With 

' Get range from shtArticles 
With shtArticles 
    If Not .Range("A2") = "" Then 
     arrarticles = .Range("A2", .Cells(Rows.Count, "A").End(xlUp)).Resize(, 3) 
    End If 
End With 

' Get range from shtAmount (The new sheet) 
With shtAmount 
    If Not .Range("A2") = "" Then 
     arramount = .Range("A2", .Cells(Rows.Count, "A").End(xlUp)).Resize(, 2) 
    End If 
End With 

' Get range from shtSummary 
With shtSummary 
    If Not .Range("A2") = "" Then 
     'Here I have no idea where to even begin 
    Else 
     ' If Summary sheet is blank, get data from other sheet and insert 
     ReDim tempArr(1 To UBound(arrUsers) * UBound(arrarticles), 1 To 6) 
     For u = 1 To UBound(arrUsers) 
      For i = 1 To UBound(arrarticles) 
       j = j + 1 
       tempArr(j, 1) = arrUsers(u, 1) 
       tempArr(j, 2) = arrUsers(u, 2) 
       tempArr(j, 3) = arrarticles(i, 1) 
       tempArr(j, 4) = arrarticles(i, 2) 
       tempArr(j, 6) = arrarticles(i, 3) 
      Next 
     Next 
     ' Add the data 
     .Range("A2").Resize(j, 6).Value = tempArr 
    End If 
End With 

編集を:私はちょうど私が各項目のIDを追加することができますIDをkalledユーザーと記事シートの両方に新しい列を追加しました。 SkyDriveで実際のシートを更新しました。

答えて

3

私はまずあなたの入力を完全に出力から分離することから始めます。これは経験に基づいています。数年前に会計士のために会計帳簿を作成し、総勘定元帳となるP & L.

管理情報は1枚で、GLコードは別のもの取引はまだまだあり、基本的にはマクロが行われ、4つのシートに要約と詳細のバランスシートと収支のステートメントが作成されました。

元の試みは入力側で情報を操作しようとしましたが、それは悪夢であることが判明しました。入力と出力が分離されると、管理が非常に簡単になりました。

  • 人物:つまり

    は、次のシートのようなものを持っています。

  • アイテム。
  • トランザクション。
  • 出力。

最初の3つは入力のみです。トランザクションは、どのアイテムが何人に与えられたのかのリストです(多対多の関係)。それから私は次のように実行するマクロを持っています。

まず、4番目のシートを完全に消去します(出力)。その後、Peopleシートの各アクティブな人物について、Transactionシートを参照して、その人物に添付されているトランザクションのOutputエントリを作成します。

ところで、あなたは歴史を維持し、残した人々の周りの記録を保持したいかもしれないので、私は上記の「アクティブ」と言います。それはPeopleシートのなんらかのフラグです。

おそらく、このプロセスの一環としてアイテムと価格を調べる必要があります。

有効な人または項目がない取引エントリなど、マクロの一部としてエラーを報告することもできます。

また、一部の人物が同じ名前を持っている可能性があることを考慮する必要があります(同じ商品であっても定期的に価格が変わる可能性があります)。そのために、誤って識別される可能性がないように、各人物とアイテムに一意のIDを付けることが賢明かもしれません。これらの一意のIDはトランザクションシートに格納されます。


私が議論したマクロは37Kで計量されているので、ここにロットを投稿することはできません。しかし、これは、トランザクションのシートを処理し、残高を持つアカウントのページを更新し、メイン処理ビットです:

Rem Attribute VBA_ModuleType=VBAModule 
Option VBASupport 1 
Option Explicit 

Public Const TxnSheet = "Txns" 
Public Const TxnColId = "a" 
Public Const TxnColDate = "b" 
Public Const TxnColAcct = "c" 
Public Const TxnColAmt = "d" 
Public Const TxnColDesc = "e" 
Public Const TxnColNotes = "f" 
Public Const TxnRowStart = "2" 

Public Const AcctSheet = "Accts" 
Public Const AcctColReport = "a" 
Public Const AcctColType = "b" 
Public Const AcctColBold = "c" 
Public Const AcctColItalic = "d" 
Public Const AcctColFontPlus1 = "e" 
Public Const AcctColOther2 = "f" 
Public Const AcctColOther3 = "g" 
Public Const AcctColOther4 = "h" 
Public Const AcctColOther5 = "i" 
Public Const AcctColLevel = "j" 
Public Const AcctColSign = "k" 
Public Const AcctColAcct = "l" 
Public Const AcctColVal = "m" 
Public Const AcctColNotes = "n" 
Public Const AcctRowStart = "2" 

' Process all transactions. 

Sub ProcessTransactions() 
    Dim TxnId As Integer 
    Dim Balance As Double 
    Dim WsTxn As Worksheet 
    Dim WsAcct As Worksheet 

    Dim RowTxn As String 
    Dim RowAcct As String 

    Dim RowTxn2 As String 
    Dim RowTxn3 As String 

    Dim StartDate As Date 
    Dim EndDate As Date 
    Dim CutoffDate As Date 
    Dim PastCutoff As Boolean 

    ' Get user-configurable stuff 

    StartDate = GetConfig("start_date") 
    EndDate = GetConfig("end_date") 
    CutoffDate = GetConfig("cutoff_date") 
    PastCutoff = False 

    ' For filling in transaction IDs. 

    TxnId = 1 

    Set WsTxn = Worksheets(TxnSheet) 
    Set WsAcct = Worksheets(AcctSheet) 
    RowTxn = TxnRowStart 


    ' Select the worksheet and cell so we can see what's happening. 

    WsTxn.Select 
    Range(TxnColAcct + RowTxn).Select 
    Range(TxnColAcct + RowTxn).Show 

    ' Process all transaction lines. 

    Do While Range(TxnColAcct + RowTxn).Value <> "" 
     ' Check for start of transaction (non-blank date). 

     If Range(TxnColDate + RowTxn).Value <> "" Then 
      ' Check date within range. 

      If Range(TxnColDate + RowTxn).Value < StartDate Or Range(TxnColDate + RowTxn).Value > EndDate Then 
       Range(TxnColDate + RowTxn).Select 
       MsgBox "ERROR: ProcessTransactions: Date out of range" 
       End 
      End If 

      If Range(TxnColDate + RowTxn).Value > CutoffDate Then 
       PastCutoff = True 
      End If 

      ' Start of transaction, fill in transaction ID and increment. 

      Range(TxnColId + RowTxn).Value = TxnId 
      TxnId = TxnId + 1 

      ' Check that transaction is balanced. 

      RowTxn2 = FindNextTxn(RowTxn) 
      RowTxn3 = PrevRow(RowTxn2) 

      Balance = 0 
      Do While RowTxn2 <> RowTxn 
       RowTxn2 = PrevRow(RowTxn2) 
       Balance = Balance + Range(TxnColAmt + RowTxn2).Value 
      Loop 
      If Balance > 0.001 Or Balance < -0.001 Then 
       Range(TxnColAmt + RowTxn + ":" + TxnColAmt + RowTxn3).Select 
       MsgBox "ERROR: ProcessTransactions: Unbalanced transaction" 
       End 
      End If 
     Else 
      ' Not transaction start, clear transaction ID column. 

      Range(TxnColDate + RowTxn).Clear 
     End If 

     ' Get account line, error if account not in accounts worksheet. 

     RowAcct = FindAccount(Range(TxnColAcct + RowTxn).Value) 
     If RowAcct = "" Then 
      MsgBox "ERROR: ProcessTransactions: Invalid account '" & Range(TxnColAcct + RowTxn).Value & "'" 
      End 
     End If 

     ' Update accounts value. 

     If Not PastCutoff Then 
      WsAcct.Range(AcctColVal + RowAcct) = WsAcct.Range(AcctColVal + RowAcct) + Range(TxnColAmt + RowTxn).Value 
     End If 

     ' Move to next transaction. 

'  Sleep 50 
     RowTxn = NextRow(RowTxn) 
     Range(TxnColAcct + RowTxn).Select 
     Range(TxnColAcct + RowTxn).Show 
    Loop 

    Range(TxnColDate + RowTxn).Select 
    Range(TxnColDate + RowTxn).Show 
End Sub 

それは、シートレイアウトを知らなくても、その有用ではないかもしれないが、それは私が送信できずに行うことができます最善ですあなたは全体のワークブックです。

+0

ああ、これはもっと似ているようです。 :)しかし、それは少し難しいとより複雑なようです。あなたは少しの例を気にしますか?それともあまりにも多くのことを求めているだろうか?あなたがもっと多くのポイントを望むなら、私はこの質問に賞金を追加することができます:)それは基本的に私はまだ自信がないループです。 –

+0

@ケニー、私はマクロを投稿しようとしましたが、彼らは37Kで体重があり、私は30Kに制限されています。 – paxdiablo

+0

これでコードを追加しました。これは基本的に私が現在いる場所です。 –

関連する問題