Excel 2007 VBA копирует строки x раз на основе текстового фильтра - PullRequest
1 голос
/ 01 февраля 2012

Я новичок в VBA и не могу обернуться вокруг наиболее эффективного способа сделать это - то, что я ищу, - это способ скопировать мои данные в строки ниже активной ячейки на основе частоты.

Пример данных выглядит так:

Name     Value  Frequency   Date
Steve    10     Annual      01/03/2012 
Dave     25     Quarterly   01/03/2012 
Sarah    10     Monthly     01/03/2012 
Gavin    27     Quarterly   01/04/2012

И в этом случае я бы хотел, чтобы Сара добавила во все строки с шагом в один месяц до марта 2013 года. Это будет означать добавление в 12 строк с апреля 2012 года по март 2013 года с именем, значением и частотой. оставаясь постоянной.

Для Стива я хотел бы добавить одну строку за март 2013 Для Дейва я хотел бы добавить в 3 строки (один раз в три месяца)

Если первая дата будет 1 апреля 2012 года, а периодичность будет ежегодной. Я не хотел бы ничего добавлять, поскольку до марта 2013 года другой даты нет.

Для приведенного выше примера результат будет:

Name    Value   Frequency   Date
Steve   10  Annual      01/03/2012
Steve   10  Annual      01/03/2013
Dave    25  Quarterly   01/03/2012
Dave    25  Quarterly   01/07/2012
Dave    25  Quarterly   01/11/2012
Dave    25  Quarterly   01/03/2013
Sarah   10  Monthly     01/03/2012
Sarah   10  Monthly     01/04/2012
Sarah   10  Monthly     01/05/2012
Sarah   10  Monthly     01/06/2012
Sarah   10  Monthly     01/07/2012
Sarah   10  Monthly     01/08/2012
Sarah   10  Monthly     01/09/2012
Sarah   10  Monthly     01/10/2012
Sarah   10  Monthly     01/11/2012
Sarah   10  Monthly     01/12/2012
Sarah   10  Monthly     01/01/2013
Sarah   10  Monthly     01/02/2013
Sarah   10  Monthly     01/03/2013
Gavin   27  Quarterly       01/04/2012
Gavin   27  Quarterly       01/08/2012
Gavin   27  Quarterly       01/12/2012

Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 02 февраля 2012

Дэвин

Вильгельм, задал правильный вопрос. Я все еще продолжаю и предполагаю, что, говоря «Ежеквартально», вы просто хотите добавить 4 месяца.

Я также предполагаю, что ( Я полагаю, что я прав в этом, хотя ) вы хотите продолжать увеличивать даты до того времени, когда они будут меньше 1 марта 2013 года (неважно, является ли это ЕЖЕГОДНО, КВАРТАЛЬНО или ЕЖЕМЕСЯЧНО)

Пожалуйста, попробуйте этот код. Я уверен, что это можно сделать более совершенным. ;)

ПРОВЕРЕНО И ИСПЫТАНО

Option Explicit

Sub Sample()
    Dim ws As Worksheet, ws1 As Worksheet
    Dim i As Long, j As Long, LastRow As Long
    Dim boolOnce As Boolean
    Dim dt As Date

    On Error GoTo Whoa

    Application.ScreenUpdating = False

    '~~> Input Sheet
    Set ws = Sheets("Sheet1")
    '~~> Output Sheet
    Set ws1 = Sheets("Sheet2")
    ws1.Cells.ClearContents

    '~~> Get the last Row from input sheet
    LastRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row

    boolOnce = True

    '~~> Loop through cells in Col A in input sheet
    For i = 2 To LastRow
        j = ws1.Range("A" & ws1.Rows.Count).End(xlUp).Row + 1

        Select Case UCase(ws.Range("C" & i).Value)
            Case "ANNUAL"
                dt = DateAdd("yyyy", 1, ws.Range("D" & i).Value)
                '~~> Check if the date is less than 1st march 2013
                If dt <= #3/1/2013# Then
                    ws1.Range("A" & j & ":A" & j + 1).Value = ws.Range("A" & i).Value
                    ws1.Range("B" & j & ":B" & j + 1).Value = ws.Range("B" & i).Value
                    ws1.Range("C" & j & ":C" & j + 1).Value = ws.Range("C" & i).Value
                    ws1.Range("D" & j).Value = ws.Range("D" & j).Value
                    ws1.Range("D" & j + 1).Value = DateAdd("yyyy", 1, ws.Range("D" & i).Value)
                End If
            Case "QUARTERLY"
                dt = DateAdd("M", 4, ws.Range("D" & i).Value)
                Do While dt <= #3/1/2013#
                    ws1.Range("A" & j).Value = ws.Range("A" & i).Value
                    ws1.Range("B" & j).Value = ws.Range("B" & i).Value
                    ws1.Range("C" & j).Value = ws.Range("C" & i).Value
                    If boolOnce = True Then
                        ws1.Range("D" & j).Value = DateAdd("M", -4, dt)
                        boolOnce = False
                    Else
                        ws1.Range("D" & j).Value = dt
                    End If
                    dt = DateAdd("M", 4, ws1.Range("D" & j).Value)
                    j = j + 1
                Loop
                boolOnce = True
            Case "MONTHLY"
                dt = DateAdd("M", 1, ws.Range("D" & i).Value)
                Do While dt <= #3/1/2013#
                    ws1.Range("A" & j).Value = ws.Range("A" & i).Value
                    ws1.Range("B" & j).Value = ws.Range("B" & i).Value
                    ws1.Range("C" & j).Value = ws.Range("C" & i).Value
                    If boolOnce = True Then
                        ws1.Range("D" & j).Value = DateAdd("M", -1, dt)
                        boolOnce = False
                    Else
                        ws1.Range("D" & j).Value = dt
                    End If
                    dt = DateAdd("M", 1, ws1.Range("D" & j).Value)
                    j = j + 1
                Loop
                boolOnce = True
        End Select
    Next i

LetsContinue:
    Application.ScreenUpdating = True
    Exit Sub
Whoa:
    MsgBox Err.Description
    Resume LetsContinue
End Sub

Snapshot

enter image description here

1 голос
/ 02 февраля 2012

Вам нужна функция, которая переводит частотный текст в количество месяцев (назовем его MonthFreq, возвращая целое число).

Это будет делать то, что вы хотите:

MaxDate = DateSerial(2013, 4, 1)
Do Until Origin.Cells(OriginRow, NameColumn).Value = ""
    SourceDate = Origin.Cells(OriginRow, DateColumn).Value
    Do Until SourceDate >= MaxDate
        ' Copy origin row to destiny.
        Destiny.Cells(DestinyRow, DateColumn).Value = SourceDate

        SourceDate = DateAdd("m", MonthFreq(Origin.Cells(OriginRow, FreqColumn).Value), SourceDate)
        DestinyRow = DestinyRow + 1
    Loop
    OriginRow = OriginRow + 1
Loop

Origin - это рабочий лист с исходными данными, Destiny - это рабочий лист, на котором будут сохранены расширенные данные.OriginRow - это текущая строка, анализируемая на рабочем листе Origin (начинается с первой строки).OriginColumn - это текущая строка, записываемая на листе Destiny (начинается с первой строки).SourceDate будет добавлено через несколько месяцев до достижения MaxDate.

...