Выбор и печать нескольких листов одновременно на основе значения ячейки на каждом листе

#excel #vba

Вопрос:

У меня есть документ с более чем 500 листами, и я пытаюсь распечатать все те, где G1 = «Печать», как один документ.

Мои шаги состоят в том, чтобы создать массив и сохранить соответствующие имена листов. Далее необходимо выбрать эти листы из массива и распечатать их.

 Sub Help()   Dim MyArray() As Variant  Dim I As Long  Dim MyArray_Count As Integer  MyArray_Count = 0   Worksheet_Count = ActiveWorkbook.Worksheets.Count   For I = 1 To Worksheet_Count  If Worksheets(I).Range("G1").Value = "Print" Then  MyArray_Count = MyArray_Count   1  MyArray(MyArray_Count) = ActiveWorkbook.Worksheets(I).Name ' 'Having error here  End If   Next I   Worksheets(MyArray).Select 'having error here   End Sub  

Ответ №1:

Есть много способов сделать это, но вам не хватает одной важной детали Redim Preserve .

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

 Sub Help()  Dim ws As Worksheet  Dim MyArray() As String  ReDim MyArray(0)   For Each ws In ActiveWorkbook.Worksheets  If ws.Range("G1").Value = "Print" Then  If Len(MyArray(0)) gt; 0 Then ReDim Preserve MyArray(UBound(MyArray)   1)  MyArray(UBound(MyArray)) = ws.Name  End If  Next   If Len(MyArray(0)) gt; 0 Then  ActiveWorkbook.Worksheets(MyArray).Select  Else  MsgBox "none found"  End If   End Sub  

Примечание: Имейте в виду, что «Печать» в вашей ячейке-это не то же самое, что «печать» или «ПЕЧАТЬ».

Вот лучшее If заявление для решения этой проблемы:

 If UCase$(Trim$(ws.Range("G1").Value)) = "PRINT" Then  

Ответ №2:

Словарь против массива

Словарь

  • Вы не знаете, сколько листов будет добавлено, поэтому использование словаря представляет собой более подходящее (простое) решение. Кроме того, использование For Each...Next цикла делает его более читабельным и подчеркивает, что количество листов не имеет значения.
 Option Explicit  Sub HelpDictionary()   Dim wb As Workbook: Set wb = ActiveWorkbook  ' If you're dealing with the workbook containing this code, instead use:  'Dim wb As Workbook: Set wb = ThisWorkbook    Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")    Dim ws As Worksheet  Dim cString As String    ' Add the worksheet names to the dictionary.  For Each ws In wb.Worksheets  cString = CStr(ws.Range("G1").Value)  If StrComp(cString, "Print", vbTextCompare) = 0 Then ' 'PRINT = print'  dict(ws.Name) = Empty ' only interested in the keys  End If  Next ws    ' Check if any worksheet name was added.  If dict.Count = 0 Then ' no worksheet name added  MsgBox "No worksheets to select.", vbExclamation  Exit Sub  'Else ' at least one worksheet name was added  End If    wb.Worksheets(dict.Keys).Select   MsgBox "The following worksheets are selected: " _  amp; vbLf amp; Join(dict.Keys, vbLf), vbInformation   End Sub  

Массив

  • Это также правильное решение. Сравните его со словарным решением, чтобы увидеть, насколько оно сложнее.
 Sub HelpArray()   Dim wb As Workbook: Set wb = ActiveWorkbook  ' If you're dealing with the workbook containing this code, instead use:  'Dim wb As Workbook: Set wb = ThisWorkbook    Dim aCount As Long: aCount = wb.Worksheets.Count    Dim MyArray() As String: ReDim MyArray(1 To aCount) ' to fit 'a'll names    Dim cString As String  Dim a As Long ' 'a'll worksheets  Dim p As Long ' worksheets to 'p'rint    ' Add the worksheet names to the array.  For a = 1 To aCount  cString = CStr(Worksheets(a).Range("G1").Value)  If StrComp(cString, "Print", vbTextCompare) = 0 Then ' 'PRINT = print'  p = p   1  MyArray(p) = wb.Worksheets(a).Name  End If  Next a    ' Check if any worksheet name was added.  If p = 0 Then ' no worksheet name added  MsgBox "No worksheets to select.", vbExclamation  Exit Sub  'Else ' at least one worksheet name was added  End If    ' Resize if not all worksheet names.  If p lt; aCount Then ' not all worksheet names added  ReDim Preserve MyArray(1 To p)  'Else ' all worksheet names added  End If    wb.Worksheets(MyArray).Select   MsgBox "The following worksheets are selected: " _  amp; vbLf amp; Join(MyArray, vbLf), vbInformation   End Sub