2013-12-06 7 views
5

Это дает мне головную боль .. Im пытается сделать следующее:VBA Excel отдельный диапазон даты в ячейках

Это данные у меня есть, у меня есть имена элемента и дата начала и дата окончания. Я хочу, чтобы эти данные были днем, а не в диапазоне больше (так что я могу загрузить его в базу данных, у меня есть то, что есть в день).

Я не знаю, могу ли я сделать это без использования VBA, но я думаю, что быстрыми темпами будет VBA.

Текущие данные:

╔═══════╦════════════╦════════════╗ 
║ name ║ start date ║ end date ║ 
╠═══════╬════════════╬════════════╣ 
║ foo1 ║ 25-11-2013 ║ 28-11-2013 ║ 
║ foo2 ║ 25-11-2013 ║ 28-11-2013 ║ 
║ foo3 ║ 25-11-2013 ║ 28-11-2013 ║ 
║ foo4 ║ 25-11-2013 ║ 28-11-2013 ║ 
║ foo5 ║ 25-11-2013 ║ 28-11-2013 ║ 
║ foo6 ║ 28-11-2013 ║ 28-11-2013 ║ 
║ foo7 ║ 28-11-2013 ║ 28-11-2013 ║ 
║ foo8 ║ 28-11-2013 ║ 28-11-2013 ║ 
║ foo9 ║ 28-11-2013 ║ 28-11-2013 ║ 
║ foo10 ║ 28-11-2013 ║ 28-11-2013 ║ 
║ foo11 ║ 29-11-2013 ║ 30-11-2013 ║ 
║ foo12 ║ 29-11-2013 ║ 30-11-2013 ║ 
║ foo13 ║ 29-11-2013 ║ 30-11-2013 ║ 
║ foo14 ║ 29-11-2013 ║ 30-11-2013 ║ 
║ foo15 ║ 29-11-2013 ║ 30-11-2013 ║ 
╚═══════╩════════════╩════════════╝ 

И я хочу, чтобы отделить от имен днем, чтобы получить это:

╔═══════╦════════════╗ 
║ name ║ date ║ 
╠═══════╬════════════╣ 
║ foo1 ║ 25-11-2013 ║ 
║ foo2 ║ 25-11-2013 ║ 
║ foo3 ║ 25-11-2013 ║ 
║ foo4 ║ 25-11-2013 ║ 
║ foo5 ║ 25-11-2013 ║ 
║ foo1 ║ 26-11-2013 ║ 
║ foo2 ║ 26-11-2013 ║ 
║ foo3 ║ 26-11-2013 ║ 
║ foo4 ║ 26-11-2013 ║ 
║ foo5 ║ 26-11-2013 ║ 
║ foo1 ║ 27-11-2013 ║ 
║ foo2 ║ 27-11-2013 ║ 
║ foo3 ║ 27-11-2013 ║ 
║ foo4 ║ 27-11-2013 ║ 
║ foo5 ║ 27-11-2013 ║ 
║ foo6 ║ 28-11-2013 ║ 
║ foo7 ║ 28-11-2013 ║ 
║ foo8 ║ 28-11-2013 ║ 
║ foo9 ║ 28-11-2013 ║ 
║ foo10 ║ 28-11-2013 ║ 
║ foo11 ║ 29-11-2013 ║ 
║ foo12 ║ 29-11-2013 ║ 
║ foo13 ║ 29-11-2013 ║ 
║ foo14 ║ 29-11-2013 ║ 
║ foo15 ║ 29-11-2013 ║ 
║ foo11 ║ 30-11-2013 ║ 
║ foo12 ║ 30-11-2013 ║ 
║ foo13 ║ 30-11-2013 ║ 
║ foo14 ║ 30-11-2013 ║ 
║ foo15 ║ 30-11-2013 ║ 
╚═══════╩════════════╝ 

Спасибо заранее.

+2

+1 для хорошо отформатированного вопроса! Как вы создали этот формат таблицы для публикации? Это приятно и легко читается :) – Blackhawk

+2

Эти текстовые таблицы должны быть стандартизированы для запросов Excel, требующих выборки ... Отлично. –

+1

Вы можете сделать это, просто используя copy/paste ... но как только вы их отделите, как вы узнаете, является ли дата датой начала или датой окончания? Разве это не имеет значения? Кажется, это должно быть два поля, а не одно. –

ответ

0

Самый быстрый и простой способ - использовать VBA. Следующий код проходит через значения из столбца A и C, записывает их под существующими данными в столбцах A и B и удаляет данные в столбце C.

Sub SeperateDateRange() 
    Dim Ws As Worksheet 
    Dim nCol As Integer 

    'Define sheet 
    Set Ws = ActiveSheet 

    nCol = 1 '<~~ Defines the number of columns before the date columns 

    Application.ScreenUpdating = False 

    'Loops throuh cells 
    For i = 1 To ActiveSheet.Cells(Rows.Count, nCol + 2).End(xlUp).Row - 1 Step 1 
     For j = 0 To Ws.Cells(i + 1, nCol + 2).Value - Ws.Cells(i + 1, nCol + 1).Value Step 1 

      With Ws.Cells(Ws.Cells(Rows.Count, 1).End(xlUp).Row + 1, 1) 
       For k = 0 To nCol - 1 Step 1 
        .Offset(0, k).Value = Ws.Cells(i + 1, k + 1).Value 
       Next k 
       .Offset(0, nCol).Value = DateSerial(Year(Ws.Cells(i + 1, nCol + 1).Value), Month(Ws.Cells(i + 1, nCol + 1).Value), Day(Ws.Cells(i + 1, nCol + 1).Value) + j) 
      End With 
     Next j 
    Next i 

    'Deletes last column with dates 
    Ws.Cells(1, nCol + 2).EntireColumn.Delete 

    Application.ScreenUpdating = True 
End Sub 

UPDATE: Из-за последующий вопрос в комментариях, код будет изменен таким образом, что переменная nCol определяет количество столбцов с именами до даты столбцов. Если макрос должен работать на данных, представленных в исходном вопросе, то nCol = 1. Если есть три столбца с именами до даты viables, то nCol = 3.

+0

Вам не хватает даты между датами. если у меня есть строка с именем «foo» от «25-11-2013» до «27-11-2013». Тогда результатом будет три строки с именем «foo» с датой «25-11-2013», «26- 11-2013 "и" 27-11-2013 " – gepex

+0

Я вижу - я обновил код. Надеюсь, это выполнит свою работу. –

+0

спасибо !!!!!! – gepex

1

В сочетании с ответом @ SorenHoltenHansen, это должно заставить вас туда, куда вы хотите отправиться. Этот класс примет диапазон начала и окончания даты, и он рассчитает весь диапазон дат, который вы затем можете использовать в коде.

Создайте новый класс, назовем его «clsDateRange», и добавьте следующий код:

Option Compare Database 
Option Explicit 

Private m_colDates As Collection 

Public Sub InitStartEnd(ByVal dtStart As Date, ByVal dtEnd As Date) 
    Set m_colDates = New Collection 
    Dim tempDate As Date 
    For tempDate = dtStart To dtEnd Step 1 
     m_colDates.Add DateValue(tempDate) 
    Next 
End Sub 

Public Property Get Dates() As Collection 
    Set Dates = m_colDates 
End Property 

Вы можете пойти целый боров и реализует интерфейс сбора, но это должно быть достаточно для ваших нужд. Если у вас будут очень большие диапазоны дат и вы хотите быть умными, вы можете сохранить только даты начала и окончания и генерировать промежуточные даты только тогда, когда они необходимы, но я хотел бы иметь возможность использовать Для ... Каждый без необходимости определять [_NewEnum] и все под-свойства коллекции.

Вот несколько тестов в модуле "mdlMain", так что вы можете увидеть, как вы можете использовать его:

Public Sub Main() 
    Dim oDateRange As New clsDateRange 
    Dim varDate As Variant 

    oDateRange.InitStartEnd "25-11-2013", "27-11-2013" 
    For Each varDate In oDateRange.Dates() 
     MsgBox varDate 
    Next 

    oDateRange.InitStartEnd "28-11-2013", "28-11-2013" 
    For Each varDate In oDateRange.Dates() 
     MsgBox varDate 
    Next 

    oDateRange.InitStartEnd "29-11-2013", "30-11-2013" 
    For Each varDate In oDateRange.Dates() 
     MsgBox varDate 
    Next 

End Sub 

Кстати, dates are actually just 64-bit floating point numbers, Doubles. Они представляют the range January 1, 100 to December 31, 9999. Каждый день равен 1, поэтому весь диапазон [-657434, 2958465]. Времена дня представлены как дробные десятичные части. Полночь - * .0, полдень * .5, 3:30 - ~ .645833333333333. В настоящее время (в моем часовом поясе), это 6 декабря 2013 года 1:27 вечера. Согласно VBA в ближайшем окне ?CDbl(now()), это 41614.5608680556.

Так вот почему я могу пробежать диапазон дат в цикле for, добавляя каждый раз, чтобы увеличить день.

+0

Это должно сделать это. – James

Смежные вопросы