Excel基于循环引用动态创建值

时间:2014-03-30 14:28:44

标签: excel excel-vba excel-2010 vba

以下是我要填充的示例表:

Item   |   Date   |   Assigned Date
------------------------------------
 1     |   Apr 1  |     
 2     |   Apr 1  |     
 3     |   Apr 1  |     
 4     |   Apr 2  |     
 5     |   Apr 2  |     
 6     |   Apr 2  |     
 7     |   Apr 2  |     
 8     |   Apr 3  |     
 9     |   Apr 4  |     
 10    |   Apr 4  |         

基于此表

Date   |   Max Allowed   |   Current Count
----------------------------------------------
Apr 1  |      2          |      
Apr 2  |      4          |
Apr 3  |      1          |
Apr 4  |      2          |
Apr 5  |      2          |

我试图找出一种基于工作列中的数据创建值的方法。我知道这会给我循环引用,并且不知道如何实现这一点。现在我打开迭代计算,并对(分配日期)执行一个标识,看看我是否应该使用第一个可用日期,或者将其递增,直到它跟在第二个表之后。但是,使用迭代计算,countif无法正常工作。

我需要使用VBA吗?因此,在一天结束时,两个表将需要:

Item   |   Date   |   Assigned Date
------------------------------------
 1     |   Apr 1  |     Apr 1
 2     |   Apr 1  |     Apr 1     
 3     |   Apr 1  |     Apr 2     
 4     |   Apr 2  |     Apr 2     
 5     |   Apr 2  |     Apr 2     
 6     |   Apr 2  |     Apr 2     
 7     |   Apr 2  |     Apr 3     
 8     |   Apr 3  |     Apr 4     
 9     |   Apr 4  |     Apr 4     
 10    |   Apr 4  |     Apr 5         
Date   |   Max Allowed   |   Current Count
----------------------------------------------
Apr 1  |      2          |       2
Apr 2  |      4          |       4
Apr 3  |      1          |       1
Apr 4  |      2          |       2
Apr 5  |      2          |       1

如果需要VBA,请您指点一些资源或代码示例,以帮助我完成此操作?非常感谢你提前。

1 个答案:

答案 0 :(得分:0)

如果没有VBA,我认为你无法完成这项任务。以下是我将如何填充表格(假设基于下图的设置):

tables

Option Explicit
Sub PopulateTables()

'declare variables
Dim DataSheet As Worksheet, ControlSheet As Worksheet
Dim LastDataRow As Long, LastControlRow As Long, DataIdx As Long, _
    CurrentCount As Long, MaxAllowed As Long, _
    ControlDateCol As Long, DataDateCol As Long, _
    ControlMaxAllowedCol As Long, ControlCurrentCountCol As Long, _
    DataItemCol As Long, DataAssignedDateCol As Long, _
    ControlStartRow As Long
Dim DataDate As Date, ControlDate As Date
Dim ControlDateRange As Range, ControlStartRange As Range, _
    DataAssignedDateRange As Range

'assign sheets for easy reference, initialize location variables
Set DataSheet = ThisWorkbook.Worksheets("data")
Set ControlSheet = ThisWorkbook.Worksheets("control")
ControlDateCol = 1
ControlMaxAllowedCol = 2
ControlCurrentCountCol = 3
DataItemCol = 1
DataDateCol = 2
DataAssignedDateCol = 3


'identify the last rows of the sheets
LastDataRow = DataSheet.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
LastControlRow = ControlSheet.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row

'identify the control date range
Set ControlDateRange = Range(ControlSheet.Cells(2, ControlDateCol), ControlSheet.Cells(LastControlRow, ControlDateCol))

'loop through the data table
For DataIdx = 2 To LastDataRow

    DataDate = DataSheet.Cells(DataIdx, DataDateCol)
    Set ControlStartRange = ControlDateRange.Find(DataDate, SearchOrder:=xlByRows, SearchDirection:=xlNext)
    'error trap - if date isn't found, error out
    If ControlStartRange Is Nothing Then
        MsgBox ("Date in row " & DataIdx & " not found on control sheet, exiting!")
        Exit Sub
    End If

    'start the counting of rows
    ControlStartRow = ControlStartRange.Row

'the "restart" point
AssignCountAndMaxValues:

    'assign the count and max allowed values
    CurrentCount = ControlSheet.Cells(ControlStartRow, ControlCurrentCountCol).Value
    MaxAllowed = ControlSheet.Cells(ControlStartRow, ControlMaxAllowedCol).Value

    'decision logic
    Select Case CurrentCount
    'something weird happened, the count somehow became higher than the max
    Case Is > MaxAllowed
        MsgBox ("An error has occurred, current count is greater than max allowed. Exiting...")
        Exit Sub
    'have not hit the maximum allowable number of dates for this row
    Case Is < MaxAllowed
        DataSheet.Cells(DataIdx, DataAssignedDateCol) = ControlSheet.Cells(ControlStartRow, ControlDateCol)
        CurrentCount = CurrentCount + 1
        ControlSheet.Cells(ControlStartRow, ControlCurrentCountCol).Value = CurrentCount
    'maximum number of dates for this row has been reached, try the next row
    Case Else
        ControlStartRow = ControlStartRow + 1
        GoTo AssignCountAndMaxValues
    End Select

    'error trap - run out of control dates to compare against
    If ControlStartRow > LastControlRow Then
        MsgBox ("Error, control sheet is out of dates to compare. Exiting...")
        Exit Sub
    End If

Next DataIdx

'format the Excel-numerical dates as short dates
Set DataAssignedDateRange = Range(DataSheet.Cells(2, DataAssignedDateCol), DataSheet.Cells(LastDataRow, DataAssignedDateCol))
DataAssignedDateRange.NumberFormat = "m/d/yyyy"

End Sub