2013-09-07 3 views
1

Я новичок в VBA и пытаюсь написать макрос, который берет книгу с несколькими листами данных и форматирует ее для печати. На каждом листе имеются таблицы информации (например, отчеты о прибылях и убытках). Я хочу, чтобы этот код мог работать для рабочих книг, которые создаются, но имеет одинаковую базовую информацию. Это означает, что мне нужно найти начало и конец данных на каждом листе, потому что он не всегда находится в одном месте (кто-то может начинать с «А1», а кто-то из «В4» и т. Д.).VBA - проблемы динамического выбора диапазона

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

Sub FormatWorkbook() 
Dim ws As Worksheet 
Dim rowStart As Long 
Dim columnStart As Long 
Dim rowEnd As Long 
Dim columnEnd As Long 
Dim printStart As String 
Dim printEnd As String 

Application.ScreenUpdating = False 

'Turn off print communication 
Application.PrintCommunication = False 
'Loop through sheets 
For Each ws In Worksheets 
    'Make current sheet activesheet 
    ws.Select 
    'Set rowStart, columnStart, rowEnd, and columnEnd to the used range 
    With ActiveSheet 
     rowStart = .Cells.Find(what:="*", after:=.Range("A1"), LookAt:=xlPart, LookIn:=xlFormulas, searchorder:=xlByRows, searchdirection:=xlNext, MatchCase:=False).Row 
     columnStart = .Cells.Find(what:="*", after:=.Range("A1"), LookAt:=xlPart, LookIn:=xlFormulas, searchorder:=xlByColumns, searchdirection:=xlNext, MatchCase:=False).Column 
     rowEnd = .Cells.Find(what:="*", after:=.Range("A1"), LookAt:=xlPart, LookIn:=xlFormulas, searchorder:=xlByRows, searchdirection:=xlPrevious, MatchCase:=False).Row 
     columnEnd = .Cells.Find(what:="*", after:=.Range("A1"), LookAt:=xlPart, LookIn:=xlValues, searchorder:=xlByColumns, searchdirection:=xlPrevious, MatchCase:=False).Column 
    End With 

Это всего лишь часть программы, но я больше всего смущен. Если бы кто-нибудь мог помочь, я бы очень признателен. Кроме того, если есть лучший способ выполнить эту задачу, я все уши. Остальная часть моего кода ниже для справки.

'Insert or Delete Space above the first used row 
    If rowStart < 4 Then 
     Do While rowStart < 4 
      Range("1:1").Select 
      Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove 
      ws.Select 
      With ActiveSheet 
       rowStart = .Cells.Find(what:="*", after:=.Range("A1"), LookIn:=xlValues, searchorder:=xlByRows, searchdirection:=xlNext).Row 
      End With 
     Loop 
    ElseIf rowStart > 4 Then 
     Do While rowStart > 4 
      Range("1:1").Select 
      Selection.Delete Shift:=xlUp 
      ws.Select 
      With ActiveSheet 
       rowStart = .Cells.Find(what:="*", after:=.Range("A1"), LookIn:=xlValues, searchorder:=xlByRows, searchdirection:=xlNext).Row 
      End With 
     Loop 
    End If 

    'I think I need to adjust the columnStart, rowEnd, and columnEnd values after inserting and deleting rows 
    ws.Select 
    printStart = ActiveSheet.Cells(1, columnStart).Address 
    printEnd = ActiveSheet.Cells(rowEnd, columnEnd).Address 

    'Format headers, footers, and set the print area 
    ActiveSheet.PageSetup.CenterHeaderPicture.Filename = _ 
     "\\antilles\MyDocs\xxxx\My Documents\My Pictures\xxxx.png" 
    With ActiveSheet.PageSetup 
     .CenterHeader = "&G" 
     .LeftFooter = "&""Palatino Linotype,Regular""&F" 
     .CenterFooter = "&""Palatino Linotype,Regular""Prepared By: xxxx" 
     .RightFooter = "&""Palatino Linotype,Regular""&D" 
     .PrintArea = printStart & ":" & printEnd 
    End With 

Next ws 
Application.PrintCommunication = True 

End Sub

ответ

0

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

Некоторые проблемы с вашим кодом:

  • Если лист содержит что-то, найдите возвращает диапазон. Диапазон имеет ряд, чтобы ваши заявления работали. Но если рабочий лист пуст, Find возвращает Nothing. Вы должны использовать Set Rng = .Cells.Find ..., затем тест Rng, чтобы не быть Ничем перед тем, как получить доступ к Rng.Row или Rng.Column. См. Код ниже, если это не ясно.

  • Обратите внимание на после в After:=.Range("A1"). Поиск не проверяет .Range("A1"), пока он не проверит каждую другую ячейку и не вернется к началу. В любом примере, в котором начальная точка равна .Range("A1"), направление поиска будет xlPrevious, поэтому оно немедленно обертывает и начинает поиск из нижней правой ячейки. Попробуйте After:=.Cells(Rows.Count, Columns.Count), когда направление поиска - xlNext.

Был более ранний вопрос, похожий на ваш. Я опубликовал некоторый код, который показал набор методов поиска последней строки или столбца и ситуаций, в которых они терпят неудачу. Я предлагаю вам посетить этот ответ и попробовать код: https://stackoverflow.com/a/18220846/973283.

Удачи и счастливого программирования VBA.

+0

Я посмотрел на ваш предыдущий ответ, и это действительно помогает найти, где строки и столбцы начинаются и останавливаются. – user2755920

+0

@ пользователь2755920. Я рад, что это помогло. –

1

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

dim iRow as integer 
For iRow = 1 to ... 
    cells(iRow,65000).end(xlup).select 
    if activecell.row = 1 then 
     activecell.entirecolumn.delete 
     exit For 
    endif 
next iRow 

По возможности сила какая-то структура на листе. Затем перейдите см http://www.ozgrid.com/VBA/ExcelRanges.htm Когда прибегая к помощи, включают в себя

OzGrid | Пирсон | Tushar | "Г-н Excel" | Эрландсен | Пельтье | dailydoseofexcel

в строку поиска.

+0

Спасибо за помощь! Я все еще работаю над кодом. Поисковый запрос Google замечателен. – user2755920

+0

хороший совет по поиску в Google. –

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