перенос данных с одного листа на другие в зависимости от даты

Автор Аиша, 20.03.2012, 12:58

« назад - далее »

Аиша

Доброго времени сутук!
Помогите пожалуйста автоматизировать перенос данных с одного листа на другие в зависимости от даты, содержащейся в столбце A.
Нашла тему с похожим вопросом, пыталась переделать предложенный там макрос под себя, но что то ничего не получается, переносятся все данные без учета даты.
Помогите пожалуйста, в макросах понимаю мало, ибо только учусь на чужих примерах ((

GWolf

Здравствуйте, Аиша!

Чужой макрос, без коментариев, это как минное поле без карты минирования.
Поэтому, попробую объяснить по-своему, как я бы решал подобную задачу.
А, уважаемый nilem, если сочтет возможным, прокоментирует и свой макрос и объяснит, вероятно, как его - макрос, мог бы модифицировать для своих задачь новичок.

И так:

Sub perenosPoDate()
   'объявим переменные
   Dim nR As Long '- для счетчика строк, как длинное целое
   Dim oDate As String '- для хранения ответа пользователя о дате для которой проводим отбор
   Dim param As String ' - для хранения даты из строки, опраштваемой в очередном шаге цикла Do ... Loop
   
   'запросим у пользователя, для какой даты следует выполнить обработку?
   oDate = InputBox(Prompt:="Введите дату для которой" & Chr(10) & "следует собрать данные:", _
                    Title:="Запрос системы", _
                    Default:=Date)
   If IsDate(oDate) = True Then '- проверяем, что ввел пользователь: если Дату, то
       'Мы должны перемещаться по столбцу "А", т.е. по колонке № 1
       nR = 3 '- стартовое значение счетчика строк = 3
       Do
           param = Cells(nR, 1).Text
           'теперь сравним значение двух строковых переменных, и если они совпали, то
           If param = oDate Then
               'скопируем значения из нужных нам ячеек в нужные нам места
               
               'ЗДЕСЬ СОБСТВЕННО КОПИРОВАНИЕ
               
           End If
           nR = nR + 1 'с каждым оборотом цикла Do ... Loop, увеличим счетчик на 1
       Loop While ThisWorkbook.ActiveSheet.Cells(nR, 1).Text <> "" 'будем выполнять цикл Do ... Loop, пока _
                                                                    текстовое значение в ячейке Этой книги.Актив- _
                                                                    ного листа.Cells(nR, 1) не равно "" - ячейка не _
                                                                    содержит текста.
   Else ' если не Дату, то
       MsgBox "Введенное значение параметра неидентифицируется как дата!" & Chr(10) & _
              "Я немогу работать с таким форматом параметра, ДОСВИДАНИЯ!", vbCritical + vbOKOnly, "Ответ системы:"
       nR = 0
       oDate = ""
       Exit Sub
   End If
End Sub


САМО КОПИРОВАНИЕ НЕ ОПИСАЛ, потому что не понял что и куда копировать. Напишите сами, или поясните - допишу.
Успеха.

P.S.
Вижу ужо, как в меня летят тапки! Согласен! Цикл Do ... Loop - "не самая быстрая телега" при перемещении по ячейкам листа и, массивом было бы быстрее. Но, ... для новичка, и подобный путь, вероятно возможен. Потом, поднаторев - освоит и массивы.
Если не прав - поправте.
Путей к вершине - множество. Этот один из многих!

Аиша

простите,
поясню:
на листе "вставка" находятся данные по заявкам за несколько месяцев, мне нужно распределить их на листы по дате заведения (столбец A): в примере листы 12,13,14 соответствуют 12.03.2012, 13.03.2012, 14.03.2012; на них нужно перенести всю информацию по заявкам за указанные даты. На листе "ИТОГИ" производятся расчеты с использованием этих листов (но это я уже сделала с помощью формул).
Поскольку по любой из этих заявок могут меняться, а так же ежедневно добавляются новые, необходим макрос для автоматизации процесса переноса данных на листы с датами.
В предложенном макросе, который хотела переделать, на нужном листе (у меня это лист "12") вводится желаемая дата, нажимается "кнопка" и данные за указанную дату должны быть полностью перенесены. После моей попытки настроить макрос под свою задачу данные переносятся, но полностью, не учитывая введенную дату.

Аиша

Цитата: GWolf от 20.03.2012, 14:35
Здравствуйте, Аиша!

Чужой макрос, без коментариев, это как минное поле без карты минирования.
Поэтому, попробую объяснить по-своему, как я бы решал подобную задачу.
А, уважаемый nilem, если сочтет возможным, прокоментирует и свой макрос и объяснит, вероятно, как его - макрос, мог бы модифицировать для своих задачь новичок.

И так:

Sub perenosPoDate()
   'объявим переменные
   Dim nR As Long '- для счетчика строк, как длинное целое
   Dim oDate As String '- для хранения ответа пользователя о дате для которой проводим отбор
   Dim param As String ' - для хранения даты из строки, опраштваемой в очередном шаге цикла Do ... Loop
   
   'запросим у пользователя, для какой даты следует выполнить обработку?
   oDate = InputBox(Prompt:="Введите дату для которой" & Chr(10) & "следует собрать данные:", _
                    Title:="Запрос системы", _
                    Default:=Date)
   If IsDate(oDate) = True Then '- проверяем, что ввел пользователь: если Дату, то
       'Мы должны перемещаться по столбцу "А", т.е. по колонке № 1
       nR = 3 '- стартовое значение счетчика строк = 3
       Do
           param = Cells(nR, 1).Text
           'теперь сравним значение двух строковых переменных, и если они совпали, то
           If param = oDate Then
               'скопируем значения из нужных нам ячеек в нужные нам места
               
               'ЗДЕСЬ СОБСТВЕННО КОПИРОВАНИЕ
               
           End If
           nR = nR + 1 'с каждым оборотом цикла Do ... Loop, увеличим счетчик на 1
       Loop While ThisWorkbook.ActiveSheet.Cells(nR, 1).Text <> "" 'будем выполнять цикл Do ... Loop, пока _
                                                                    текстовое значение в ячейке Этой книги.Актив- _
                                                                    ного листа.Cells(nR, 1) не равно "" - ячейка не _
                                                                    содержит текста.
   Else ' если не Дату, то
       MsgBox "Введенное значение параметра неидентифицируется как дата!" & Chr(10) & _
              "Я немогу работать с таким форматом параметра, ДОСВИДАНИЯ!", vbCritical + vbOKOnly, "Ответ системы:"
       nR = 0
       oDate = ""
       Exit Sub
   End If
End Sub


САМО КОПИРОВАНИЕ НЕ ОПИСАЛ, потому что не понял что и куда копировать. Напишите сами, или поясните - допишу.
Успеха.

P.S.
Вижу ужо, как в меня летят тапки! Согласен! Цикл Do ... Loop - "не самая быстрая телега" при перемещении по ячейкам листа и, массивом было бы быстрее. Но, ... для новичка, и подобный путь, вероятно возможен. Потом, поднаторев - освоит и массивы.
Если не прав - поправте.

Спасибо Вам огромное, здорово, что написали пояснения к действиям. Буду изучать

Wasilic

Цитата: GWolf от 20.03.2012, 14:35
Чужой макрос, без коментариев, это как минное поле без карты минирования.
Оочень правильно ответил GWolf!

Автор: Аиша Применить тот макрос  тоже можно, но он не для Вашего случая.
Вот еще пример простого решения Вашей задачи.
Копирование только видимых колонок в их естественном порядке.
Sub KOPIR()
 Application.ScreenUpdating = False
 Dim SZ, I, DK As Date
 SZ =  3
 DK = [a2]
 With Sheets("вставка")
    For I = 3 To .Cells(Rows.Count, 1).End(xlUp).Row
      If .Cells(I, 1) = DK Then
         Worksheets("вставка").Range("A" & I & ":AP" & I).SpecialCells(xlVisible).Copy
         ActiveSheet.Range("A" & SZ).Select
         Selection.PasteSpecial Paste:=xlPasteValues
         SZ = SZ + 1
      End If
    Next I
 End With
 Application.ScreenUpdating = True
End Sub
Может и я на что сгожусь ... Если сгодился, можете меня по+благодарить+.

Аиша

Здорово! Спасибо огромное.
подскажите пожалуйста, как ему объяснить, что прежде, чем переносить данные, нужно очистить диапазон A3:AQ1000 ?

ShAM


GWolf

Добрый день!

Цитата: Аиша от 21.03.2012, 09:23
... как ему объяснить, что прежде, чем переносить данные, нужно очистить диапазон A3:AQ1000 ?

На самом деле, ответ на Ваш вопрос может быть и простым и сложным:
- простой: Range("A3:AQ1000").ClearContents

- сложный: сложность тут относительная. Она заключается в понимании того, что есть очищаемый диапазон в поле листа, куда переносятся данные. Если это ЛЮБАЯ последовательность строк, расположенных ниже третьей. А с первой по третью - заголовок таблицы. То имеет смысл не задавать нижнюю границу диапазона жестко (AQ1000), а определять ее программно, исходя из занятого информацией количества строк - столбцов.
Один из вариантов такого определения может быть такой:
Sub interval()
   'объявим переменные
   Dim iDiapazon As Range '- для хранения используемого диапазона
   Dim nREnd As Long '- для определяемого номера крайней занятой строки
   Dim nCEnd As Long '- для определяемого номера крайнего занятого столбца
   
   'И так,
   With ThisWorkbook.ActiveSheet 'для этой книги и активного листа в этой книге
       Set iDiapazon = .UsedRange ' "загрузим" в переменную используемый диапазон
       With iDiapazon ' для переменной
           'найдем координату
           nREnd = .Row + .Rows.Count - 1 'крайней строки
           nCEnd = .Column + .Columns.Count - 1 'крайнего столбца
       End With
       Set iDiapazon = Nothing '"обнулим" переменную
       
       'для диапазона, определяемого ячейкой с координатами (3, 1) -> "A3" и _
        ячейкой с координатами (nREnd, nCEnd), очистим контекст
       Range(.Cells(3, 1), .Cells(nREnd, nCEnd)).ClearContents
   End With
End Sub


Успеха.
Путей к вершине - множество. Этот один из многих!

GWolf

Цитата: ShAM от 21.03.2012, 10:30
Перед
With Sheets("вставка")
Вставьте
Range("A3:AQ1000").ClearContents


Осмелюсь заметить, если код Range("A3:AQ1000").ClearContents поставить не до, а после  With Sheets("вставка")
и начать его с точки, т.е. вот так: .Range("A3:AQ1000").ClearContents, то исполнятся данная инструкция будет только для листа "вставка", что бывает иногда очень важно.
Путей к вершине - множество. Этот один из многих!

ShAM

Цитироватьисполнятся данная инструкция будет только для листа "вставка", что бывает иногда очень важно.
С "иногда очень важно" согласен. Но в данном случае (если правильно понял) данные с листа "вставка" разносятся по другим листам и очищать лист "вставка" будет не хорошо. :)

Аиша

Цитата: GWolf от 21.03.2012, 11:53
имеет смысл не задавать нижнюю границу диапазона жестко (AQ1000), а определять ее программно, исходя из занятого информацией количества строк - столбцов.

ммм.... интересно.. но мне все таки нужно ограничить очистку по столбцам до столбца AQ... В Вашем варианте это как сделать?

Аиша

2 часа убила на попытки сделать так, что бы по нажатию одной кнопки данные обновлялись на всех листах (с листа "вставка") при условии, что на каждом листе в ячейке a2 стоит нужная дата.... не выходит каменный цветок....  :-\

GWolf

Цитата: Аиша от 21.03.2012, 12:29
... нужно ограничить очистку по столбцам до столбца AQ... В Вашем варианте это как сделать?

Столбец "AQ" имеет номер 43. Поэтому, вот в этой строке кода:  Range(.Cells(3, 1), .Cells(nREnd, nCEnd)).ClearContents, вместо nCEnd ставим 43, т.е. код будет выглядеть так: Range(.Cells(3, 1), .Cells(nREnd, 43)).ClearContents. Ну или так:

nCEnd=43
Range(.Cells(3, 1), .Cells(nREnd, nCEnd)).ClearContents

для ShAM
все верно, но я подумал с кем мы дело имеем:
Цитироватьв макросах понимаю мало, ибо только учусь на чужих примерах
;) без обид!
Путей к вершине - множество. Этот один из многих!

GWolf

Цитата: Аиша от 21.03.2012, 12:36
2 часа убила на попытки сделать так, что бы по нажатию одной кнопки данные обновлялись на всех листах (с листа "вставка") при условии, что на каждом листе в ячейке a2 стоит нужная дата.... не выходит каменный цветок....  :-\

Могу лишь предположить: кода то нет!? = Нужно организовать один цикл в котором перебирать листы, куда следует вставить данные и при переборе считывать в переменную
Цитироватьнужную дату
, а уже относительно этой даты во внутреннем цикле пробегать лист "вставка" и "отбирать", в смысле копировать в очередной просматриваемый лист данные с соответствующей датой.
А проще, на мой взгляд, обработку организовать так что бы "пробегая" лист "вставка", предварительно отсортированный макросом по колонке дата, создавать новый лист, переименовывать его и копировать в него все строки пока не изменится значение в поле дата.
Путей к вершине - множество. Этот один из многих!

Wasilic

Цитата: Аиша от 21.03.2012, 12:36
2 часа убила на попытки сделать так, что бы по нажатию одной кнопки данные обновлялись на всех листах (с листа "вставка") при условии, что на каждом листе в ячейке a2 стоит нужная дата.... не выходит каменный цветок....  :-\
Надо грызть камень VBA а не цветок.  :)
Так пойдет?
Пример с учетом того, что все имена листов будут иметь вид - 1, 2, ... 31
Может и я на что сгожусь ... Если сгодился, можете меня по+благодарить+.