Страницы: 1
RSS
VBA: перенос столбцов в новый лист через столбец циклом
 
Уважаемые программисты, можно ли к Вам обратиться помочь доработать код?
С листа "details" копируем 2 столбца, потом еще 10, но помещаем их в новый лист через 1 (начиная с 3-го столбца-2 мы уже скопировали). Файл прилагаю.

Код
Private Sub Worksheet_Activate()
Dim i As Long, j As Long, lrow As Long
Dim UserRange As Range
Dim iCells As Range
lrow = UserRange.Cells(Rows.Count, 1).End(xlUp).Row
With Sheets("details").Range("B2").CurrentRegion
Set UserRange = Sheets("details").Union(.Columns("B"), .Columns("C"), .Range("R2:AB2"))
Union(.Columns("B"), .Columns("C")).Copy Sheets("Лист1").Range("B1")
'Range("R2:AB2").Copy Cells(RowsCount, "D").End(xlUp).Offset(2)
'значения вставляются каждый раз в следующую строку
End With

'Range("R2:AB2" & lrow).Copy Sheets("Лист1").Range("D2")
For Each iCells In Sheets("details").Range("R2" & lrow & ":AB2" & lrow)
If Worksheets("details").Cells(iCells, "R2").Value > 0 Then
For W = 3 To lrow
If IsEmpty(Cells(W, 1)) Then
For j = 1 To 10 'так как нужно скопировать с R2 по AB2 -10- столбцов
Do
Cells(W, j) = Worksheets("details").Cells(iCells, j)
j = 2 * j + 1
iCells = iCells + 1
Loop Until Columns(j).Find(What:="*") Is Nothing Or j = Columns.Count
     '.PasteSpecial xlPasteAll
     .PasteSpecial xlPasteColumnWidths ' ширина столбца'
     .PasteSpecial xlPasteValues ' значения'
     .PasteSpecial xlPasteFormats ' форматы'
 
Next j
Exit For
End If
Next W
End If
Next iCells
'End With
Application.CutCopyMode = False
End Sub

На листе2 показано, как это должно выглядеть.
Изменено: irina_iv - 29.12.2018 10:05:27
 
У меня ваш архив не открылся.
 
Вот так примерно...
Изменено: irina_iv - 29.12.2018 14:46:45
 
Цитата
Private Sub Worksheet_Activate()
При активации какого листа срабатывает макрос?
Цитата
Sheets("Лист1").Range("B1")
В книге нет Листа1
 
Удалить из каждой таблицы по 1500 строк - такая проблема? Тогда, глядишь, и для макросов место найдется.
 
у кого то из форумчан была очень актуальная для вашего файла подпись: "если автоматизировать бардак, то получится автоматизированный бардак".
я думаю во многом из-за этого так много желающих разбираться в вашем файле.
 
Ну, Вы, конечно, шутники...Я и вправду удалила (случайно) лист1, хотя он там нужен. Но "бардаком" я бы не стала это называть: во-первых, я новичок, во-вторых, это таблицы, а разве можно таблицы назвать бардаком?..
Неравнодушным людям буду очень благодарна, ибо доделать макрос сама не могу пока. Копирование с листа "details" должно выглядеть как лист "pre".
P.s. Всех с прошедшими праздниками!
 
irina_iv, Не равнодушным людям трудно понять в Вашем файле чего Вы собственно хотите.
Можете описать хотелку своими словами без разгадывания шарад в неработающем коде вашего файла?
 
А можете сделать файл на одном листе  таблица 10х10 (рога, копыта), на другом , то как она должна выглядеть после копирования. В Вашем макросе нет желания разбирать ошибки.
"Все гениальное просто, а все простое гениально!!!"
 
Конечно. Два столбца "ФИО агента" и "Адрес" переносятся с листа "details" на "Лист1" и находятся рядом, остальные столбцы "аванс", "зп1-зп10" - переносятся на лист "Лист1" через один столбец (чтобы между можно было вписывать даты). То есть все должно выглядеть как на листе 'pre'. Было бы замечательно, если можно было бы сделать форматирование как на листе "pre" на листе1. (цвета, толщина, центрирование и т.д.). Конечно, не мучайтесь :). Я на этот код потратила недели 2, и он еще не работает...
P.s. Спасибо, люди добрые,-у меня даже надежда появилась!
P.p.s. В принципе, можно скопировать на лист "pre', только чтобы форматирование этой таблицы сохранилось.
Изменено: irina_iv - 09.01.2019 15:04:42
 
Немного не понятно, зачем копировать столбцы, копируйте весь лист, затем вставьте столбцы где вам нужно, а лишнее удалите. Если таблица имеет одинаковую структуру всегда, то можно макрорекодером записать макрос, а после лишнее удалить.
Изменено: Nordheim - 09.01.2019 15:11:19
"Все гениальное просто, а все простое гениально!!!"
 
Ну, можно, конечно, и так сделать. А как у меня будут тогда добавляться новые значения? Каждый раз заново копировать лист?
Только я думала, что так будет интереснее.
P.s. С макрорекордером обращаться не умею...
 
Цитата
irina_iv написал:
А как у меня будут тогда добавляться новые значения?
А как они у Вас сейчас добавляются, или будут добавляться после копирования?
Цитата
irina_iv написал:
P.s. С макрорекордером обращаться не умею...
Т.е. макросы писать можете, а макрорекодером пользоваться не умеете? Как это так?
"Все гениальное просто, а все простое гениально!!!"
 
Наверно копирование листа вам не подойдет, если у Вас уже будут заполнены доп столбцы
"Все гениальное просто, а все простое гениально!!!"
 
Да, здесь бы лучше циклом или еще как-то, как быстро и точно...
А мой точно не хотите посмотреть? ;) Может, быстрее будет?..
 
Цитата
irina_iv написал:
А мой точно не хотите посмотреть?
Нет. Но на вскидку, это к чему относится?
Код
     .PasteSpecial xlPasteColumnWidths ' ширина столбца'
     .PasteSpecial xlPasteValues ' значения'
     .PasteSpecial xlPasteFormats
"Все гениальное просто, а все простое гениально!!!"
 
irina_iv, пробуйте (не тестировал, т.к. не хватило времени - на работе). Предполагается, что лист с индесом 1 - лист с исходными данными, с индексом 3 - место выгрузки:
Код
Sub aaa()
Dim arr(), a&, c%, zz()
zz = Array("Аванс", "Дата", "ЗП")
With Sheets(1)
  a = Application.CountA(Intersect(.UsedRange, .Columns(3)))
  ReDim arr(1 To a, 1 To 25)
  arr(1, 4) = zz(0): arr(1, 5) = zz(1)
  For c = 1 To 10: arr(1, c * 2 - 1 + 5) = zz(2) & "_" & c: arr(1, c * 2 + 5) = zz(1) & "_" & c: Next
  For c = 1 To 3: arr(1, c) = .Cells(2, c).Value: Next
  For a = 2 To a
    For c = 2 To 3: arr(a, c) = .Cells(a + 1, c).Value: Next
    arr(a, 4) = .Cells(a + 1, 18): arr(a, 1) = a - 1
    For c = 1 To 10: arr(a, c * 2 - 1 + 5) = .Cells(a + 1, c + 18): Next
  Next
End With
With Sheets(4)
  .UsedRange.Clear: .UsedRange.Clear
  With .[a1].Resize(UBound(arr, 1), UBound(arr, 2))
    .Borders.LineStyle = xlContinuous: .Value = arr
  End With
  .Rows(1).AutoFilter: .UsedRange.EntireColumn.AutoFit
End With
End Sub
Изменено: Anchoret - 10.01.2019 10:33:35
 
Вариант для файла из сообщения №3
Код
Sub test()
'   -----------------------------------------------
    Dim i&, j&, sht As Worksheet, sh As Worksheet, lrow&
'   -----------------------------------------------
    Application.ScreenUpdating = False
    Set sht = ThisWorkbook.Worksheets("как должно быть")
    Set sh = ThisWorkbook.Worksheets("details")
    With sh
        lrow = .UsedRange.Rows.Count
        .Range("b1:c" & lrow).Copy
        sht.[b1].PasteSpecial xlPasteValues
        j = 6
        For i = 19 To 28
           .Range(.Cells(1, i), .Cells(lrow, i)).Copy
           sht.Cells(1, j).PasteSpecial xlPasteValues
           j = j + 2
        Next i
    End With
    Application.ScreenUpdating = True
    Set sh = Nothing: Set sht = Nothing
End Sub
"Все гениальное просто, а все простое гениально!!!"
 
Anchoret, Nordheim,
спасибо большое, очень тронута ;). Единственное, что пишут: "can`t execute code in break mode".
Nordheim, "как должно быть" - это название листа, на который копируют?
 
Цитата
irina_iv написал:
Nordheim, "как должно быть" - это название листа, на который копируют?
Совершенно верно.
"Все гениальное просто, а все простое гениально!!!"
 
irina_iv, да, там была ошибка и не одна. Изменил код выше. Лист выгрузки теперь имеет индекс 4. Соответственно все индексы листов можно переименовать названиями реальных листов.

П.С.: Есть один нюанс - если даты планировалось вводить вручную и вне зависимости от времени запуска этого макроса, то грусть-печаль. Макрос затирает при выгрузке все данные под выгружаемой таблицей.
 
Да, Anchoret. данные планировалось по датам вводить вручную. То есть просто скопировать с интервалом столбцы (кроме первых двух)...
Не бросайте меня, Вы и Nordheim - моя последняя надежда ;)...
 
irina_iv, по сути код идентичный коду от Nordheim, только не очень читабельный :
Код
Sub bbb()
Dim a&, c%, zz(), sh1 As Worksheet, sh2 As Worksheet
zz = Array("Аванс", "Дата", "ЗП")
Set sh1 = Sheets(1): Set sh2 = Sheets(4)
  If sh2.AutoFilterMode = True Then sh2.ShowAllData
  a = Application.CountA(Intersect(sh1.UsedRange, sh1.Columns(3)))
  sh2.Range("D1:D" & a).Value = sh1.Range("R2:R" & a + 1).Value
  sh2.Range("A1:C" & a).Value = sh1.Range("A2:C" & a + 1).Value
  For c = 1 To 10: sh2.Cells(1, c * 2 - 1 + 5) = zz(2) & "_" & c: sh2.Cells(1, c * 2 + 5) = zz(1) & "_" & c: Next
  sh2.Cells(1, 4) = zz(0): sh2.Cells(1, 5) = zz(1)
  For c = 1 To 10
    sh2.Range(sh2.Cells(2, c * 2 - 1 + 5), sh2.Cells(a, c * 2 - 1 + 5)).Value = sh1.Range(sh1.Cells(3, c + 18), sh1.Cells(a + 1, c + 18)).Value
  Next
  sh2.[a1].Resize(a, 25).Borders.LineStyle = xlContinuous
  sh2.UsedRange.EntireColumn.AutoFit
End Sub
Изменено: Anchoret - 10.01.2019 12:08:28
 
Цитата
Anchoret написал:
не очень читабельный
Возможно так будет более "читабелно"  ;)
Скрытый текст
"Все гениальное просто, а все простое гениально!!!"
 
Nordheim, точно)
irina_iv, есть у меня стойкое подозрение, что макросы здесь и не нужны. Т.е. достаточно формул типа "=A2=такой-то лист!A3" и т.д..
 
Есть подозрение что irina_iv, на примере макросов по этой задаче, продолжит изучение VBA, что то почерпнет, увидит ошибки допущенные в собственном коде, и попытается в дальнейшем, продолжить автоматизацию работы в Excel.  :D
"Все гениальное просто, а все простое гениально!!!"
 
Можно Вас, Anchoret, Nordheim еще немного помучать? :)
Anchoret, оригинально протаскивать, но замучаешься :).
Мне нужно чтобы только копировались:
"ФИО агента", "адрес" (из начала таблицы) и кусочек, начиная с ["аванс", "зп1"-"зп10"]. В квадратных скобках то, что должно копироваться через столбец на новый лист. Столбцы дата 1-дата 10 я прописала вручную, но так даже лучше.
Насколько я поняла, копирование должно быть на лист1, но у меня произошло также копирование на лист "pre", причем в принципе правильно, но 2 лишних столбца: столбец 2 с нумерацией (у меня уже был столбец с нумерацией) и столбец 5 (пустой). И изменился формат таблицы. Не очень понятно...
 
Вот такое получилось...
 
Честно говоря, какая то ерунда получается, наверно следует таблицы , как то более грамотно составить, или я чего то не понимаю.
"Все гениальное просто, а все простое гениально!!!"
 
irina_iv, рыба закончилась, настала пора удочки:
- Выберите любой из вариантов кода,
- введите в нужном месте название листа-получателя
- зайдите в редактор VBE
- пошагово (F8) выполните макрос
Страницы: 1
Наверх