Vba excel перенос данных с одного листа на другой

Решение задачи по копированию данных с одного листа на другой без использования и с использованием массивов. Вызов из кода VBA Excel других процедур.

Условие задачи по копированию данных

На одном листе расположен список повторяющихся городов с информацией о предприятиях общепита:

Исходная таблица задания №1

Исходная таблица задания №1

Необходимо данные по каждому городу перенести в одну строку на другом листе (таблица обрезана справа):

Часть результирующего списка задания №1

Часть результирующего списка задания №1

Решение копированием с листа на лист

Это решение значительно проще, чем с использованием массивов, но более медленное. При больших объемах информации обработка может длиться достаточно долго. Решение достигается путем присваивания значений ячеек из таблицы первого листа ячейкам второго листа.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

Sub Resheniye1()

Dim n1 As Long, n2 As Long, n3 As Long, n4 As Long, _

i1 As Long, gorod As Variant

n1 = Sheets(«Лист1»).Cells(1, 1).CurrentRegion.Rows.Count

  For i1 = 1 To n1

    With Sheets(«Лист1»)

      If gorod <> .Cells(i1, 1) Then

        gorod = .Cells(i1, 1)

        n2 = 1

        n3 = n3 + 1

        n4 = 1

      Else

        n2 = 2

      End If

      Do While .Cells(i1, n2) <> «»

        Sheets(«Лист2»).Cells(n3, n4) = .Cells(i1, n2)

        n4 = n4 + 1

        n2 = n2 + 1

      Loop

    End With

  Next

End Sub

Переменные:

  • n1 – количество строк в исходной таблице;
  • n2 – номер столбца текущей ячейки исходной таблицы, к которой обращается цикл;
  • n3 – номер строки текущей ячейки на втором листе;
  • n4 – номер столбца текущей ячейки на втором листе;
  • i1 – счетчик цикла For… Next;
  • gorod – переменная с наименованием города, предназначенная для контроля за сменой текущего города, который обрабатывается циклом.

Решение с использованием массивов

Циклы в массивах работают очень быстро, но решение с ними может быть сложнее, чем при простом присваивании значений одних ячеек другим. В этом примере для упрощения кода две процедуры записаны отдельно и в нужные моменты вызываются для исполнения.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

‘Объявление глобальных переменных

‘в разделе Declarations

Dim massiv1 As Variant, n2 As Long, _

n3 As Long, i1 As Long, txt1 As Variant

‘Исполняемая процедура для решения

‘задания вторым способом

Sub Resheniye2()

Dim n1 As Long, gorod As Variant

With Sheets(«Лист1»).Cells(1, 1)

    massiv1 = .CurrentRegion

    n1 = .CurrentRegion.Rows.Count

    n2 = .CurrentRegion.Columns.Count

End With

n3 = 0

txt1 = «»

  For i1 = 1 To n1

    If gorod <> massiv1(i1, 1) Then

      If txt1 <> «» Then

        Call Vstavka

      End If

        gorod = massiv1(i1, 1)

        txt1 = massiv1(i1, 1)

        Call Kopirovanie

    Else

        Call Kopirovanie

    End If

    If i1 = n1 Then

        Call Vstavka

    End If

  Next

End Sub

‘Копирование данных из массива в

‘строковую переменную через разделитель

Sub Kopirovanie()

Dim i2 As Long

  For i2 = 2 To n2

    If massiv1(i1, i2) <> Empty Then

      txt1 = txt1 & «|» & massiv1(i1, i2)

    End If

  Next

End Sub

‘Обработка данных из строковой

‘переменной в дополнительных массивах и

‘вставка очередной строки на второй лист

Sub Vstavka()

Dim n4 As Long, massiv2 As Variant, _

massiv3 As Variant, i3 As Long

n3 = n3 + 1

massiv2 = Split(txt1, «|»)

n4 = UBound(massiv2)

ReDim massiv3(0 To 0, 0 To n4)

  For i3 = 0 To n4

    massiv3(0, i3) = massiv2(i3)

  Next

Sheets(«Лист2»).Range(Cells(n3, 1), _

Cells(n3, n4 + 1)).Value = massiv3

End Sub

Подпрограммы Kopirovanie и Vstavka используются в цикле For... Next процедуры Resheniye2 по два раза, поэтому их коды вынесены за пределы процедуры Resheniye2 и вызываются по мере необходимости.

Переменные:

  • massiv1 – его элементам присваиваются значения ячеек исходной таблицы;
  • massiv2 – одномерный массив, заполняемый данными из переменной txt1;
  • massiv3 – двумерный массив, заполняемый данными из одномерного массива massiv2 и используемый для вставки очередной строки на второй лист;
  • txt1 – сюда копируются через разделитель значения элементов массива massiv1, предназначенные для заполнения очередной строки на втором листе;
  • n1 – количество строк в исходной таблице;
  • n2 – количество столбцов в исходной таблице;
  • n3 – номер текущей строки на втором листе;
  • n4 – количество столбцов текущей строки на втором листе (соответствует количеству элементов массива massiv2);
  • i1, i2, i3 – счетчики цикла For… Next;
  • gorod – переменная с наименованием города, предназначенная для контроля за сменой текущего города, который обрабатывается циклом.

Переменные, использующиеся более чем в одной процедуре, объявлены как глобальные в разделе Declarations программного модуля.


На одном листе таблица из этой таблицы нужно перенести данные для расчета в квитанции, другой лист. Например в ячейку на листе 2 фиО если на первой странице Новиков Илья Васильевич она должна отобразиться в ячейке A4 «=’1′!C5» потом сумма переработки, она относится к «=’1′!AS5», потом вычеты они относятся к «=’1′!AW5» и так далее, как вы выше писали, так и надо прописать. Все эти данные относятся к строке пять, следующий человек к строке 6 и все те же данные. Вот как макрос прописать я незнаю, пробывал у меня не получилось.

Добавлено через 11 минут
Алгоритм
На листе 2 нажимаю на ячейку A4, в этой ячейке ставлю формулу «=’1′!AW5», далее под графой «Сумма переработки» на листе 2 ставлю «=’1′!AS5», далее аналогично под графой «Вычеты»
ставлю «=’1′!AW5», далее под графой «Командировочны» ставлю «=’1′!AT5», далее на листе 2 под графой «доплата за а/м
ставлю «=’1′!BC5», далее так же на листе 2 под графой Оклад ставлю «=’1′!AQ5», далее на листе 2 под графой «Оклад» ставлю «=’1′!AQ5», далее под графой авнс на 2 листе ставлю
«=’1′!BF5», далее под графой доп.выплаты ставлю «=’1′!BC5».

 

sbirliko

Пользователь

Сообщений: 98
Регистрация: 22.12.2013

sbi

Уважаемые форумчане!
Помогите пожалуйста с написанием макроса, который по условию переносит данные с одного листа на другой.
Более детально указано в приложенном файле.

Заранее спасибо!
С уважением,
sbirliko

Прикрепленные файлы

  • Book1.xlsx (11.35 КБ)

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

А самому что-нить сделать, хоть макрорекордером? А поиск потерзать? Уж столько напереносили по условию, неинтересно. А стол заказов в разделе Работа.

Я сам — дурнее всякого примера! …

 

МВТ

Пользователь

Сообщений: 1198
Регистрация: 01.02.2015

#3

07.04.2015 12:56:06

Несмотря на то, что я полностью согласен с KuklP, вот код:

Код
Sub tt()
Dim L As Long: L = 3
Application.ScreenUpdating = False
With Sheets("History_")
.Unprotect
.Range("B3:I" & Cells(Rows.Count, 2).End(xlUp)).Clear
End With
Sheets("Action-Log").Activate
For I = 3 To Cells(Rows.Count, 2).End(xlUp).Row
If Cells(I, 11) = "Выполнен" Then
Range("C" & I & ":H" & I).Copy Destination:=Sheets("History_").Range("C" & L)
Range("K" & I).Copy Destination:=Sheets("History_").Range("I" & L)
With Sheets("History_").Cells(L, 2)
    .Value = L - 2
    .Borders.LineStyle = 1
End With
L = L + 1
End If
Next I
Sheets("History_").Protect
Application.ScreenUpdating = True
End Sub



 

sbirliko

Пользователь

Сообщений: 98
Регистрация: 22.12.2013

sbi

#4

07.04.2015 13:00:03

KuklP

добрый день.

к сожалению своих извилин не хватает.. даже на редактирование макросов с других примеров, которые были найдены с помощью поиска..
для примера

Код
Sub Запрос()'
    Sheets("Лист2";).Select
    Range("B2";).Select
    ActiveCell.FormulaR1C1 = _
        "=IF(ISNA(VLOOKUP(RC[-1],Лист1!R1C3:R1000C6,4,0)),"""",VLOOKUP(RC[-1],Лист1!R1C3:R1000C6,4,0))"
    Range("B2";).Select
    Selection.Copy
    Range(Selection, ActiveCell.SpecialCells(xlLastCell)).Select
    ActiveSheet.Paste
    Selection.Copy
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    Range("A1";).Select
    Application.CutCopyMode = False
End Sub

и Sub Perenos()Dim iLastRow As Long
    iLastRow = Range("A8";).End(xlDown).Row
        Range("A8:F" & iLastRow).Copy _
        Sheets("База";).Range("A" & Sheets("База";).Cells(Rows.Count, 1).End(xlUp).Row + 1)
End Sub

а сделать это через макроредактор сложно, т.к. я не знаю как создать привязку к условию(то что указано в примере)

ну уж простите, если это тема уже приелась…

 

МВТ

Пользователь

Сообщений: 1198
Регистрация: 01.02.2015

sbirliko, не расстраивайтесь и оформите код макроса как положено (кнопка <…>). Макрос я написал по Вашим таблицам, попробуйте

 

sbirliko

Пользователь

Сообщений: 98
Регистрация: 22.12.2013

sbi

МВТ

, Спасибо большое! Но, кажется ваш код написан вовсе не макроредактором….)))
И еще один момент, возможно ли удаление строк из листа Action-Log, которые были перенесены на лист History_?

 

МВТ

Пользователь

Сообщений: 1198
Регистрация: 01.02.2015

sbirliko, я и не говорил, что рекордером :). Да строки можно удалять, вставлять или менять: после окончания работы макроса таблицы никак друг с другом не связаны. Таблица-результат не имеет ссылок на Таблицу-источник, макрос просто снимает защиту, копирует отобранную информацию на другой лист и снова ставит защиту.  

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

#8

07.04.2015 13:52:05

Вариант:

Код
Sub www()
    Sheets("History_").Unprotect "123"
    Sheets("History_").UsedRange.ClearContents
    With Sheets("Action-Log").Range("B2").CurrentRegion
        .AutoFilter 10, "Выполнен"
        .Copy Sheets("History_").Range("B2")
        .Parent.AutoFilterMode = 0
    End With
    Sheets("History_").Protect "123"
End Sub

Я сам — дурнее всякого примера! …

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

#9

07.04.2015 14:08:12

Забыл. Так еще и удалит строки с исходной. И это — макрорекордером. С доработкой.

Код
Sub www()
    Sheets("History_").Unprotect "123"
    Sheets("History_").UsedRange.ClearContents
    With Sheets("Action-Log").Range("B2").CurrentRegion
        .AutoFilter 10, "Выполнен"
        .Copy Sheets("History_").Range("B2")
        .Offset(1).SpecialCells(12).EntireRow.Delete
        .Parent.AutoFilterMode = 0
    End With
    Sheets("History_").Protect "123"
End Sub 

Прикрепленные файлы

  • Book1.xlsm (17.59 КБ)

Я сам — дурнее всякого примера! …

 

МВТ

Пользователь

Сообщений: 1198
Регистрация: 01.02.2015

KuklP, идея с автофильтром хороша (не сообразил, честно), но там надо не все колонки переносить и нумерацию обновлять

 

sbirliko

Пользователь

Сообщений: 98
Регистрация: 22.12.2013

sbi

c нумерацией нет проблем, можно не обновлять… но возник другой вопросик, вернее я упустил(результат нехватки времени :sceptic:, простите, приходится писать только когда есть свободная минутка)

возможно ли доработка макроса для добавления перенесенных данных на последнюю свободную строку в листе History_?
Т.е. необходимо видить общий объем перенесенных данных(строк) за все время…

ps-скачал книгу Мэтью Харрис по VBA, буду изучать дома, по выходным… (хотя нет инета и компа дома, хоть буду теорию знать)

 

МВТ

Пользователь

Сообщений: 1198
Регистрация: 01.02.2015

sbirliko, возможно, но если Вы не удалите заранее уже перенесенные строки из таблицы-источника, они продублируются в таблице-результате. Как вариант, можно удалять уже перенесенную строку из источника. В принципе, можно даже видоизменить, чтобы при внесении Выполнено в колонку Статус, соответствующая строка переносилась в результирующую таблицу и удалялась из исходной. Подумайте, как Вы планируете организовать свои данные и исходя уже из этого можно будет пробовать что-то сделать :)

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

МВТ, Те колонки, что не надо переносить(я не обратил внимания) можно просто скрыть на время переноса.

Я сам — дурнее всякого примера! …

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

#14

07.04.2015 15:04:04

Так, вроде все учел:

Код
Sub www()
    Dim lr
    With Sheets("History_")
        lr = .Cells(65536, 2).End(xlUp).Row + 1
        .Unprotect "123"
        '        .UsedRange.Clear
    End With
    With Sheets("Action-Log").Range("B2").CurrentRegion
        .Columns("H:I").Hidden = -1
        .AutoFilter 10, "Выполнен"
        If lr = 2 Then
            .Copy Sheets("History_").Range("B2")
        Else
            .Offset(1).Copy Sheets("History_").Range("B" & lr)
        End If
        .Columns("H:I").Hidden = 0
        .Offset(1).SpecialCells(12).EntireRow.Delete
        .Parent.AutoFilterMode = 0
    End With
    Sheets("History_").Protect "123"
End Sub

Прикрепленные файлы

  • Book1.xlsm (19.65 КБ)

Изменено: KuklP07.04.2015 15:09:45

Я сам — дурнее всякого примера! …

 

sbirliko

Пользователь

Сообщений: 98
Регистрация: 22.12.2013

sbi

KuklP

и

МВТ

большое спасибо за оказанную помощь!  

 

Strizh

Пользователь

Сообщений: 76
Регистрация: 04.07.2018

Отличный макрос, огромнейшее спасибо!

 

Strizh

Пользователь

Сообщений: 76
Регистрация: 04.07.2018

#17

26.07.2019 16:38:04

KuklP, добрый день!
Вы не смогли бы изменить макрос таким образом, чтобы он смог переносить данные на другой лист ПОСТРОЧНО.
В моем документе я выбираю данные на листе 1 и переношу их на лист 2 с учетом даты.
По идее, макрос должен найти пустую строку и вставить туда скопированное значение.

Есть книга, в которой 10 листов. Нужно скопировать содержимое 8-го листа в 3-й лист.

Я пытался сделать это следующим способом:

Set CurrentWorkbook = ThisWorkbook
Set sheetTemp = CurrentWorkbook.Worksheets(8)

With Application: .ScreenUpdating = False: .DisplayAlerts = False: End With
With CurrentWorkbook
     sheetTemp.Copy CurrentWorkbook.Worksheets(3)
End With
With Application: .ScreenUpdating = True: .DisplayAlerts = True: End With

Все работает, но вместо записи в 3-й лист оно создает перед третьим листом новый лист. Как сделать так, чтобы при копировании не создавался новый лист и записывалось в существующий лист?

vikttur_Stop_RU_war_in_UA's user avatar

задан 21 сен 2018 в 10:35

Leksor's user avatar

2

Полное копирование столбцов (ширина, форматирование, значения, примечания…):

Sub CopyRange()
    Worksheets("Лист1").Columns("C:E").Copy
    Worksheets("Лист2").Columns("C:E").PasteSpecial
End Sub

или

Sub CopyRange()
    Worksheets("Лист1").Columns("C:E").Copy Worksheets("Лист2").Columns("C:E")
End Sub

Для копирования только нужного:

  Worksheets("Лист1").Range("C3:E50").Copy

  With Worksheets("Лист2").Range("C3")
      .PasteSpecial xlPasteColumnWidths ' ширина столбца'
      .PasteSpecial xlPasteValues' значения'
      .PasteSpecial xlPasteFormats' форматы'
      .PasteSpecial xlPasteFormulasAndNumberFormats ' формулы'
      ' .....'
  End With

После копирования очистить буфер:

Application.CutCopyMode = False

ответ дан 21 сен 2018 в 11:38

vikttur_Stop_RU_war_in_UA's user avatar

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

Sub Название_Макроса()

'Выделить диапазон который необходимо скопировать
Range("A1:F52").Select
'Скопировать то, что выделено
Selection.Copy
ChDir "путь к папке где лежит файл в который необходимо скопировать"
Workbooks.Open Filename:= "Название файла, который находится в папке, путь к которой указан выше"
'Выделить начальную ячейку в которую необходимо вставить скопированные данные
Range("A6").Select
'Вставить данные
ActiveSheet.Paste
'сохранить текущую книгу
ActiveWorkbook.Save
'Закрыть книгу
ActiveWorkbook.Close
End Sub

Вариант 2: В открывшейся книге запускаем макрос, чтобы он открыл нужную нам книгу, скопировал от туда нужные нам данные и вставил в нашу открытую книгу, закрыв файл из которого эти данные были скопированы

Sub Название_Макроса2()
'Открываем файл с которого нужно скопировать данные
Workbooks.Open Filename:="C:Данные.xlsx"

'Скопировать нужный диапазон в открывшейся книге на листе 1
Workbooks("Данные.xlsx").Worksheets("Лист1").Range("A16:E16").Copy
'Активируем нужную нам книгу
Workbooks("Книга1.xlsm").Activate

'Выделяем и вставляем скопированные данные в ячейку А1
ActiveWorkbook.Worksheets("Лист1").Range("A1").Select
ActiveSheet.Paste

'Закрываем книгу откуда мы скопировали данные
Workbooks("Данные.xlsx").Close

End Sub

Еще пример — Скопировать диапазоны данных из активной открытой книги Excel нескольких листов (в нашем примере 3-х листов) в другую книгу, которая хранится в определенном месте. Данные будут вставлены как значения, плюс будут перенесены форматы ячеек.

Sub Копируем_листы_в_другую_книгу()
Dim bookconst As Workbook
Dim abook As Workbook
Set abook = ActiveWorkbook 'присваиваем перменную активной книге
Set bookconst = Workbooks.Open("C:UsersUserDesktop1.xlsx") 'присваиваем перменную книге куда необходимо копировать данные

'переходим в активную книгу откуда необходимо скопировать данные
abook.Worksheets("Лист1").Activate
Range("A1:I23").Copy 'копируем определенный диапазон листа, укажите свой диапазон
bookconst.Worksheets("Лист1").Activate 'активируем лист куда необходимо вставить данные
Range("A1:I23").Select 'встаем на ячейку А1
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'вставляем только форматы ячеек
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
'второй лист
abook.Worksheets("Лист2").Activate
Range("A1:I23").Copy
bookconst.Worksheets("Лист2").Activate
Range("A1:I23").Select 'выделяем диапазон
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'вставляем только форматы ячеек
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
'третий лист
abook.Worksheets("Лист3").Activate
Range("A1:I23").Copy
bookconst.Worksheets("Лист3").Activate
Range("A1:I23").Select 'выделяем диапазон
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'вставляем только форматы ячеек
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
'сохранить текущую книгу
bookconst.Save
'Закрыть книгу
bookconst.Close
abook.Activate

End Sub

Если статья была вам полезна, то буду благодарен, если вы поделитесь ей со своими друзьями с помощью кнопок расположенных ниже.

Спасибо за внимание.

У меня есть книга Excel с 4 листами.

  1. Мастер лист
  2. test_1
  3. test_2
  4. test_3

Я хочу переместить данные из мастер-листа на все остальные листы, что я и сделал, создав макрос. Ежедневно данные мастер-листа будут увеличиваться, так как я могу учесть это изменение в макросе.

Я вставил свой существующий код ниже:

Sub sbCopyRangeToAnotherSheet()
    Sheets("Master").Range("B10:M1628").Copy
    Sheets("test_1").Activate
    Range("B9").Select
    ActiveSheet.Paste
    Application.CutCopyMode = Flase
End Sub


Sub sbCopyRangeToCRP2()
    Sheets("Master").Range("B10:M1628").Copy
    Sheets("test_2").Activate
    Range("B9").Select
    ActiveSheet.Paste
    Application.CutCopyMode = Flase
End Sub


Sub sbCopyRangeToCRP3()
    Sheets("Master").Range("B10:M1628").Copy
    Sheets("test_3").Activate
    Range("B9").Select
    ActiveSheet.Paste
    Application.CutCopyMode = Flase
End Sub

В приведенном выше коде я упомянул жестко закодированное значение диапазона мастер-листа, которое начинается с B10 и заканчивается на M1628.

В дальнейшем количество строк увеличивается **(диапазон B10 останется)** и я не хочу жестко кодировать диапазон. Как я могу сделать это?

2017-03-14 08:10

4

ответа

Решение

Я предлагаю объединить эти 3 подпрограммы в одну, которую вы можете использовать повторно, указав рабочий лист в качестве параметра:

Sub sbCopyRangeToAnotherSheet(ToSheet As Worksheet)
    Dim LastUsedRow As Long

    With Sheets("Master")
        LastUsedRow = .UsedRange.Row + .UsedRange.Rows.Count - 1
        .Range("B10:M" & LastUsedRow).Copy ToSheet.Range("B9")
    End With

    Application.CutCopyMode = False
End Sub

Затем вы можете запустить этот саб для любого имени листа, как

Sub test_1()
    sbCopyRangeToAnotherSheet Sheets("test_1")
    'and for the second sheet
    sbCopyRangeToAnotherSheet Sheets("test_2")
End Sub

2017-03-14 08:33

Я бы предложил либо использовать UsedRange свойство объекта Worksheet,

или определить именованные диапазоны на листе, которые автоматически расширяются по мере роста данных на листе, например: =OFFSET($A$1,0,0,COUNTA($A:$A),1)

2017-03-14 08:15

Вы можете использовать этот макрос

Sub CopyAll()
    Dim src As Range, dest
    With Worksheets("Master") ' set the source range
        Set src = .Range("B10:M" & .Cells(.Rows.Count, "B").End(xlUp).Row)
    End With
    For Each dest In Array("test_1", "test_2", "test_3") ' loop on destination sheets
        src.Copy Worksheets(dest).Range("B9")
    Next
End Sub

2017-03-14 08:41

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

  1. Создать точный массив
  2. Заполните данные из мастер-листа
  3. Вставьте данные.

И в этом случае вам не нужно беспокоиться о новой строке, потому что вы используете динамический массив. Смотрите пример ниже.

Sub sbCopyRangeToAnotherSheet()
Sheets("Master").Select
Dim RowNum as integer 
For i = 0 To 250000 'Count all rows
    If IsEmpty(Cells(i + 10, 2)) = False Then
        RowNum = RowNum + 1 'Count all rows which have data in it's second column
    Else
        Exit For
    End If
Next
ReDim myData(RowNum - 1, 12) As String 'create array
For i = 0 To RowNum - 1 'fill array, with data
    For j = 0 to 12
    myData(i, j) = Cells(i + 10, j+2) '+10 because you said B**10**
                                      '+2 because you said **B**10
    Next
Next

Sheets("test_1").Activate
For i = 0 To RowNum - 1 'fill array, with data
    For j = 0 to 12
    Cells(i + 10, j+2) = myData(i, j) 'Fill cells with data
    Next
Next
End Sub

2017-03-14 08:38

Копирование, с листа на лист (по нескольким условиям)

Max16

Дата: Среда, 01.06.2016, 16:18 |
Сообщение № 1

Группа: Пользователи

Ранг: Новичок

Сообщений: 11


Репутация:

0

±

Замечаний:
20% ±


Excel 2007

Добрый день уважаемые форумчане!
Вопрос Вам мой покажется возможно глупым, но если кто либо отзовется и поможет, буду благодарен.

Суть проблемы следующая:
Есть массив информации на одном из листов книги (Area1), этот самый массив нужно преобразовать в итоговую таблицу, по заданным критериям (собака, кот, попугай), вид которой представлен на (Лист4). Файл прикладываю

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

Суть макроса, как мне представляется: создать итоговую таблицу, как у меня (в самом макросе задать переменные:

собака, кот, попугай, или вынести их на отдельный лист), и по этим переменным искать значения в исходном листе. После нахождения одной из переменных (f.e. собака) — макрос находил бы последнюю строку, добавлял следующей критерий (переменную), и по нему заполнял дальше массив. В общем нужен вид, как в прикрепленном файле. Думаю в нем будет понятнее

P.S. я возможно несколько наглею, прося о такой помощи. Поэтому не судите строго

К сообщению приложен файл:

2149532.xlsm
(28.5 Kb)


123

 

Ответить

wild_pig

Дата: Среда, 01.06.2016, 16:47 |
Сообщение № 2

Группа: Проверенные

Ранг: Обитатель

Сообщений: 516


Репутация:

97

±

Замечаний:
0% ±


2003, 2013

Тут просто перенесли данные с одного листа на другой в соответствии с животинами. Это при условии совпадения столбцов с датами.
[vba]

Код

Sub uuu()
    ‘объявляем переменные
    Dim a() ‘динамический массив (пока что безразмерный)
    Dim i&, j&, rw& ‘длинные целые числа (счётчики)
‘——————-
    ‘присваиваем переменной значения диапазона с листа
    ‘массив сам примет нужные размеры
    a = Sheets(«Area1»).UsedRange.Value
    With Sheets(«Лист4») ‘ссылка на объект для упрощения синтаксиса
        ‘в пределах конструкции With … End With, если будет нужно ссылаться на «лист4» пишем точку
        For rw = 3 To .Cells(Rows.Count, 2).End(xlUp).Row ‘цикл от 3 до номера последней непустой ячейки во 2-м столбце
            If .Cells(rw, 2) <> «» Then ‘если значение ячейки не пусто то
                For i = 1 To UBound(a) ‘цикл по массиву от 1 до наибольшего индекса 1-го измерения массива (строки)
                    ‘сравниваем значение из массива со значением во 2-м столбце, ищем животное
                    If a(i, 1) = .Cells(rw, 2) Then ‘если значение элемента массива равно значению ячейки то
                        rw = rw + 1 ‘увеличиваем счётчик строк
                        For j = 1 To UBound(a, 2) ‘цикл от 1 до наибольшего индекса 2-го измерения массива (столбцы)
                            ‘вносим значения в соответствующие ячейки из массива на лист
                            .Cells(rw, j + 1) = a(i, j) ‘j + 1 потому что в массиве <=15 в 3-м столбце а на листе 4 в 4-м
                        Next
                    End If
                Next
            End If
        Next
    End With
    MsgBox «Фсё гуд!» ‘сообщеньице
End Sub

[/vba]

Сообщение отредактировал wild_pigЧетверг, 02.06.2016, 12:16

 

Ответить

Max16

Дата: Четверг, 02.06.2016, 10:45 |
Сообщение № 3

Группа: Пользователи

Ранг: Новичок

Сообщений: 11


Репутация:

0

±

Замечаний:
20% ±


Excel 2007

Уважаемый wild_pig, спасибо за помощь.

Но я к своему сожалению не до конца смог разобраться с Вашим макросом.
Я понял следующее:

[vba]

Код

Sub uuu()
‘задаем переменные массиву и значениям: i,j
    Dim a()                 
    Dim i&, j&
‘—————
‘задаем переменную a как массив (лист «Area1»)   
  a = Sheets(«Area1»).UsedRange.Value   

    ‘Задаем массив (с 3 строки 2 столбца до конца)для «Листа4»              
    With Sheets(«Лист4»)
        For rw = 3 To .Cells(Rows.Count, 2).End(xlUp).Row    

‘Если в заданном массиве ячейка не пуста, то      
If .Cells(rw, 2) <> «» Then     

       ‘Находим совпадение этой непустой ячейки на «Листе4» (с ячейкой на листе «Area1»)       
                For i = 1 To UBound(a)                   
                    If a(i, 1) = .Cells(rw, 2) Then

‘Далее. Строку принимаем равной (последняя строка +1)                    
                      rw = rw + 1                  
‘Вот тут я не совсем понимаю!!! Мы опять задаем массив для «Area1» для поиска 2-го значения?                      
                         For j = 1 To UBound(a, 2)       
‘Почему мы в качестве столбца задаем данные по строке (j)?              
                            .Cells(rw, j + 1) = a(i, j)                     
                        Next
                    End If
                Next
            End If
        Next
    End With
    MsgBox «Фсё гуд!»

[/vba]

Если Вы мне укажите, правильно ли я его (макрос) понимаю, буду признателен!
Ну и простите мою неграмотность в VBA — но насколько я знал, UBound считает предел по строке, но как я понимаю, здесь эта функция считает столбцы?


123

Сообщение отредактировал Max16Четверг, 02.06.2016, 11:02

 

Ответить

wild_pig

Дата: Четверг, 02.06.2016, 12:12 |
Сообщение № 4

Группа: Проверенные

Ранг: Обитатель

Сообщений: 516


Репутация:

97

±

Замечаний:
0% ±


2003, 2013


Не совсем так )
Код выше поправил.

 

Ответить

Max16

Дата: Четверг, 02.06.2016, 12:58 |
Сообщение № 5

Группа: Пользователи

Ранг: Новичок

Сообщений: 11


Репутация:

0

±

Замечаний:
20% ±


Excel 2007

wild_pig, Большое спасибо за помощь). Благодаря Вам — разобрался


123

 

Ответить

Max16

Дата: Четверг, 02.06.2016, 18:50 |
Сообщение № 6

Группа: Пользователи

Ранг: Новичок

Сообщений: 11


Репутация:

0

±

Замечаний:
20% ±


Excel 2007

Уважаемый wild_pig, я уже замучил Вас… В любом случае Вы очень здорово меня выручили)
Но если Вам не трудно уделите немного внимания. Я доработал немного Ваш код, по аналогии, вынеся на отдельный лист критерии: кот, собака, попугай
Благодаря этому итоговая таблица формируется без пробелов, и удобно менять критерии. Но мне нужно вставить после каждого критерия (после всех котов, собак и попугаев), строку [итого:].
Я попытался ставить код в конце макроса, но он сначала формирует массив по заданным условиям и только потом ставит строку [итого]

Собственно вот подправленный макрос:
[vba]

Код

Sub uuu()
    Dim a()
    Dim b()
    Dim i&, j&, q&
‘—————
    a = Sheets(«Area1»).UsedRange.Value
    b = Sheets(«Критерий»).UsedRange.Value ‘присвоил переменное значение диапазону Лист:»Критерий»

          With Sheets(«Лист4»)
        For rw = 3 To .Cells(Rows.Count, 2).End(xlUp).Row
            If .Cells(rw, 2) <> «» Then
                For i = 1 To UBound(a)
                  For q = 1 To UBound(b) ‘цикл по массиву от 1 до наибольшего индекса 1-го измерения массива

                                    If a(i, 1) = b(q, 1) Then ‘Если значение элекмента массива («Area1») = значению элекмента массива («Критерий»), то
                        rw = rw + 1

                                                 For j = 1 To UBound(a, 2)
                            .Cells(rw, j + 1) = a(i, j)
                            .Cells(rw + 1, 2).FormulaR1C1 = «Итого:» ‘Пытался добавить строку [итого], но он ее добавляет после того как сформирует массив по критериям
                             Next
                        End If
                    Next
                Next
            End If
        Next
        Dim lLastRow As Long
       End With
    MsgBox «Фсё гуд!»
End Sub

[/vba]

Пример также прикладываю

К сообщению приложен файл:

8284379.xlsm
(25.0 Kb)


123

 

Ответить

wild_pig

Дата: Суббота, 04.06.2016, 13:05 |
Сообщение № 7

Группа: Проверенные

Ранг: Обитатель

Сообщений: 516


Репутация:

97

±

Замечаний:
0% ±


2003, 2013

Нарисуйте ручками итоговую таблицу с итогами

 

Ответить

Max16

Дата: Суббота, 04.06.2016, 15:03 |
Сообщение № 8

Группа: Пользователи

Ранг: Новичок

Сообщений: 11


Репутация:

0

±

Замечаний:
20% ±


Excel 2007

Уважаемый wild_pig, таблицу необходимого вида я прикладываю к сообщению:

Область данных,та же (Area1)
Критерии [кот, собака, попугай] вынесены на отдельный лист (Лист!Критерии)
На листе4 — итоговая таблица. В начале имеем только строку 2 остальное подгружается макросом: Собственно таблица заполняется в соответствии с порядком расположения критериев

P.S. Итоговый вид таблицы, на листе4. Для наглядности я выделили красным цветом: критерий, синей заливкой: итого

К сообщению приложен файл:

7990798.xlsm
(23.1 Kb)


123

Сообщение отредактировал Max16Суббота, 04.06.2016, 15:04

 

Ответить

RAN

Дата: Суббота, 04.06.2016, 15:33 |
Сообщение № 9

Группа: Друзья

Ранг: Экселист

Сообщений: 5645

Голимый макрорекордер
[vba]

Код

Sub Макрос1()
    ActiveSheet.UsedRange.Copy
    Sheets.Add(After:=Sheets(Sheets.Count)).Paste
    With ActiveSheet
        .Sort.SortFields.Clear
        .Sort.SortFields.Add Key:=Range(«A1»), _
                             SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        .Sort.SetRange .UsedRange.Offset(1)
        .Sort.Header = xlGuess
        .Sort.MatchCase = False
        .Sort.Orientation = xlTopToBottom
        .Sort.SortMethod = xlPinYin
        .Sort.Apply
        .UsedRange.Subtotal GroupBy:=1, Function:=xlSum, TotalList:=Array(3, 4, 5, 6, _
                    7, 8, 9, 10), Replace:=True, PageBreaks:=False, SummaryBelowData:=True
        .UsedRange.ClearOutline
    End With
End Sub

[/vba]


Быть или не быть, вот в чем загвоздка!

 

Ответить

wild_pig

Дата: Суббота, 04.06.2016, 16:01 |
Сообщение № 10

Группа: Проверенные

Ранг: Обитатель

Сообщений: 516


Репутация:

97

±

Замечаний:
0% ±


2003, 2013

[vba]

Код

Sub uuu()
    Dim a(), b()
    Dim i&, ii&, rw&, x&, lr&
‘——————————
    ‘берём диапазоны в массивы
    a = Sheets(«Area1»).UsedRange.Value
    b = Sheets(«Критерий»).UsedRange.Value

        With Sheets(«Лист4»)
        rw = 3 ‘номер первой строки для выгрузки
        lr = .UsedRange.Rows.Count ‘номер последней строки диапазона
        If lr > 3 Then ‘если последняя строка больше первой  то
            .Rows(rw & «:» & lr).Delete ‘удаляем строки с первой по последнюю
        End If
        For i = 2 To UBound(b) ‘идём по массиву с критериями
            .Cells(rw, 2) = b(i, 1) ‘вносим название группы
            .Cells(rw, 2).Font.Bold = True ‘делаем жирным шрифт
            rw = rw + 1 ‘увеличиваем счётчик строк
            x = 1 ‘сбрасываем в начало счётчик позиций в группе
            For ii = 2 To UBound(a) ‘проходим по массиву с данными
                ‘если значение не пусто и совпадает с названием группы то
                If a(ii, 1) <> «» And a(ii, 1) = b(i, 1) Then
                    .Cells(rw, 1) = x ‘пишем номер позиции
                    For j = 1 To UBound(a, 2) ‘вносим строку из массива на лист
                        .Cells(rw, j + 1) = a(ii, j)
                    Next
                    rw = rw + 1 ‘увеличиваем счётчик строк
                    x = x + 1 ‘увеличиваем счётчик позиций
                End If
            Next
            .Cells(rw, 2) = «Итого » & LCase(b(i, 1)) & «:» ‘вносим итого
            .Cells(rw, 2).Font.Bold = True ‘делаем шрифт жирным
            rw = rw + 1 ‘увеличиваем счётчик строк
        Next
    End With
    MsgBox «Готово!» ‘радостная весть
End Sub

[/vba]
В Аrea1 нет значений больше 130 дней, зачем на Лист4 есть? Дальше будем думать что и как в итого считать?

 

Ответить

Max16

Дата: Суббота, 04.06.2016, 16:58 |
Сообщение № 11

Группа: Пользователи

Ранг: Новичок

Сообщений: 11


Репутация:

0

±

Замечаний:
20% ±


Excel 2007

wild_pig, большое спасибо)

Столбец >130 остался в примере из рабочего файла. В Area1 я просто не добавил дынные попадающие в данное условие.

По подсчету: если можно подсчитать в строке [итого] (на «листе4») сколько было котов, собак и попугаев. Это было бы очень здорово!

На всякий, прилепляю пример, как должен выглядеть подсчет

К сообщению приложен файл:

5988994.xlsm
(22.0 Kb)


123

 

Ответить

wild_pig

Дата: Суббота, 04.06.2016, 17:00 |
Сообщение № 12

Группа: Проверенные

Ранг: Обитатель

Сообщений: 516


Репутация:

97

±

Замечаний:
0% ±


2003, 2013

Это было бы очень здорово!

Это был сарказм. Уже наверное сами.

 

Ответить

Max16

Дата: Суббота, 04.06.2016, 17:28 |
Сообщение № 13

Группа: Пользователи

Ранг: Новичок

Сообщений: 11


Репутация:

0

±

Замечаний:
20% ±


Excel 2007

wild_pig, да, пора и честь знать)))

Еще раз спасибо за помощь)


123

 

Ответить

wild_pig

Дата: Суббота, 04.06.2016, 17:39 |
Сообщение № 14

Группа: Проверенные

Ранг: Обитатель

Сообщений: 516


Репутация:

97

±

Замечаний:
0% ±


2003, 2013

Вы #9 сообщение смотрели?

 

Ответить

Budkay91

Дата: Среда, 13.03.2019, 16:22 |
Сообщение № 15

Группа: Пользователи

Ранг: Прохожий

Сообщений: 2


Репутация:

0

±

Замечаний:
0% ±


Excel 2016

Здравствуйте, Господа!
Нужна помощь в написании макроса для excel 2016, для переноса ячеек с одного листа на другой, если выполняется условие.
Я в этом деле совсем начинающий, начальство нагибает закончить файл по спецодежде, а парень который начинал его делать уволился. Буду признателен!!! Очень сильно!!! SOS!!!
Для примера скидываю файлик «пример», в нем на листе «сотрудники», условие, если в столбце «Е» ячейки <= СЕГОДНЯ, то данная ячейка подсвечивается, это я допер. Теперь мне нужно с помощью макроса, чтобы тот сотрудник который подсветился автоматически попадал на лист «экзамен», помогите мне пожалуйста для примера, а свой глобальный файл я догоню доработаю!!! Заранее всем благодарен.

К сообщению приложен файл:

9569606.xlsm
(21.9 Kb)

 

Ответить

_Boroda_

Дата: Среда, 13.03.2019, 16:29 |
Сообщение № 16

Группа: Модераторы

Ранг: Местный житель

Сообщений: 16618


Репутация:

6465

±

Замечаний:
0% ±


2003; 2007; 2010; 2013 RUS

— Прочитайте Правила форума
— Создайте свою тему согласно п.5q Правил форума
Эта тема закрыта


Скажи мне, кудесник, любимец ба’гов…
Платная помощь:
Boroda_Excel@mail.ru
Яндекс-деньги: 41001632713405 | Webmoney: R289877159277; Z102172301748; E177867141995

 

Ответить

Понравилась статья? Поделить с друзьями:
  • Vba excel перенос в одной ячейке
  • Vba excel перевернуть массив
  • Vba excel перенести текст в ячейке
  • Vba excel перебрать все файлы в папке
  • Vba excel перемещение ячеек