2017-02-21 11 views
-1

Я пытаюсь создать и пропустить два разных массива, каждый из которых содержит 20 листов. Рабочие листы исходят из двух разных книг: «ежемесячно» и «еженедельно».Цитирование двух массивов рабочих таблиц в двух книгах

У меня есть следующие (после того, как некоторые предлагаемые изменения):

Dim Monthly As Excel.Workbook 
    Set Monthly = Workbooks("name of monthly workbook") 
    Dim Weekly As Excel.Workbook 
    Set Weekly = Workbooks.Open("path to weekly workbook") 

    Dim mWshtNames As Variant 
    Dim mWshtNameCrnt As Variant 
    Dim wWshtNames As Variant 
    Dim wWshtNameCrnt As Variant 

    mWshtNames = Array(Monthly.Worksheets("Reading Monthly"), Monthly.Worksheets("Writing Monthly"), Monthly.Worksheets("Science Monthly")) 
'and so on, to include 20 worksheets 
    wWshtNames = Array(Weekly.Worksheets("Reading Weekly"), Weekly.Worksheets("Writing Weekly"), Weekly.Worksheets("Science Weekly")) 
'and so on, to include 20 worksheets 

     For Each mWshtNameCrnt In mWshtNames 
      For Each wWshtNameCrnt In wWshtNames 
       MsgBox "Monthly sheet is " + mWshtNameCrnt.Name 
       MsgBox "Weekly sheet is " + wWshtNameCrnt.Name 
       'the real code will loop here; I am using MsgBox to test that the loop is working. 
      Next wWshtNameCrnt 
     Next mWshtNameCrnt 

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

Текущий результат (12 msgboxes):

  • "Ежемесячный лист Чтение Monthly", "Еженедельный лист Reading Weekly", "Еженедельный лист Запись Weekly", "Еженедельный лист Наука Weekly"
  • «Ежемесячный лист -« Письмо в месяц »,« Еженедельный листок читается еженедельно »,« Еженедельный листок пишет еженедельно »,« Еженедельный листок - это научный еженедельник »
  • « Ежемесячный лист - это журнал «Monthly Monthly», «Weekly sheet is Reading Weekly», , «Еженедельный листок пишет еженедельно», «Еженедельный лист - это научный еженедельник»

Ожидаемый результат (6 msgboxes):

  • "Ежемесячный лист Чтение Monthly", "Еженедельный лист чтения Еженедельно"
  • "Ежемесячный лист Запись Monthly", "Еженедельный лист Запись Weekly"
  • «Ежемесячный лист Наука в месяц», «Еженедельный лист Наука Weekly»

ответ на @Jeeped имеет тот же самый эффективный результат, когда Immediate Window возвращает девять результатов, где шесть, как ожидается. Мне кажется, мне нужно «Next wWshtNameCrnt» и «Next mWshtNameCrnt» активировать одновременно, но не знаю, как это записать.

+0

Не следует «и так далее, чтобы включить 20 книг» и т. Д., Чтобы включить 20 workSHEETs'? – Jeeped

+0

Что именно ваша петля должна *** делать ***? Если вы просто хотите отображать имена, вам нужно вызвать '.Name' в своих экземплярах листа. – Comintern

+1

Вы должны использовать цикл 'For' для итерации массивов, а цикл' For Every' - итерации наборов объектов. Ваши комментарии показывают, что массивы содержат * книги *, но ваш код говорит иначе, и массивы фактически содержат * рабочие листы *. Кроме того, ваши массивы хранят объекты «Worksheet», а не только их имена, поэтому имя переменной вводит в заблуждение .... и 'mWshtNames' vs' wWshtNames' трудно читать и легко ошибаться для другого. Как насчет 'MonthlySheets' и' weeklySheets' вместо? –

ответ

2

так что петли должны быть как отношения «один к одному».

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

Если это «один к одному», вам нужен только 1 цикл, и ваши два массива имеют одинаковый размер. Так сделать For цикл, который идет от LBound(anyOfTheseArrays) To UBound(anyOfTheseArraysButPreferablyTheSameYouUseToGetTheLBound):

Dim index As Long 
For index = LBound(mWshtNames) To UBound(mWshtNames) 
    Debug.Print mWshtNames(index).Name, wWshtNames(index).Name 
Next 

Для 3 элементов в каждом массиве, который даст вам 3 линии выход к немедленному панели (Ctrl + G), который является гораздо более практичным, чем MsgBox вызовов, по крайней мере для отладки.

+1

Ninja'd меня на 47 секунд! : D – YowE3K

1

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

Option Explicit 

Sub bleh() 
    Dim Monthly As Excel.Workbook, Weekly As Excel.Workbook 

    Set Monthly = Workbooks("name of monthly workbook") 
    Set Weekly = Workbooks.Open("path to weekly workbook") 

    Dim m As Long, w As Long 
    Dim mWshtNames As Variant, wWshtNames As Variant 

    'define 20 monthly workSHEET names 
    mWshtNames = Array("Lorem", "Ipsum", "Dolor", "sit", "amet", _ 
         "consectetur", "adipiscing", "elit", "Sed", "vel", _ 
         "cursus", "purus", "Vivamus", "nec", "ex", _ 
         "et", "lorem", "fringilla", "consectetur", "Fusce") 
    'define 20 weekly workSHEET names 
    wWshtNames = Array("Pellentesque", "quis", "viverra", "lorem", "ac", _ 
         "sodales", "turpis", "Morbi", "in", "vulputate", _ 
         "lectus", "Donec", "aliquam", "suscipit", "nunc", _ 
         "eget", "bibendum", "augue", "interdum", "porta") 

     For m = LBound(mWshtNames) To UBound(mWshtNames) 
      With Monthly.Worksheets(mWshtNames(m)) 
       Debug.Print .Name 
       For w = LBound(wWshtNames) To UBound(wWshtNames) 
        With Weekly.Worksheets(wWshtNames(w)) 
         Debug.Print .Name 
        End With 
       Next w 
      End With 
     Next m 

End Sub 

Этот цикл по ежемесячному листу и направляет свои .Name property на VBE-х Immediate window. Хотя этот ежемесячный рабочий лист «активен», он просматривает все еженедельные листы и отправляет их .Name в окно Immediate.

Хотя код не делает ничего целевого, он вызывает имя из процесса, который использует имя, поэтому, по крайней мере, он проверяет имя.

1

Пропустить вложенные петли целиком. Рабочие листы соответствуют друг другу тема, но только по совпадению по названию. Вместо того чтобы генерировать все полные имена (и \ или рабочие листы), прежде чем ввести свой цикл, создать индексы путем объединения объекта и тип листа и получить Worksheet ссылка внутри цикл:

Dim Monthly As Excel.Workbook 
Set Monthly = Workbooks("name of monthly workbook") 
Dim Weekly As Excel.Workbook 
Set Weekly = Workbooks.Open("path to weekly workbook") 

Dim subjects() As String 
subjects = Split("Reading,Writing,Science", ",") 
Dim weeklySheet As Worksheet 
Dim monthlySheet As Worksheet 

Dim subject As String 
For Each subject In subjects 
    Set weeklySheet = Weekly.Worksheets(subject & " Weekly") 
    Set monthlySheet = Montly.Worksheets(subject & " Monthly") 
    MsgBox "Monthly sheet is " + monthlySheet.Name 
    MsgBox "Weekly sheet is " + weeklySheet.Name 
    '"Real" code here. 
Next 

Обратите внимание, что это также позволяет использовать строго типизированные ссылки, такие как Worksheet и String, вместо того, чтобы объявлять все как Variant.

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