Excel VBA объединяет две переменные - PullRequest
1 голос
/ 06 июля 2011

У меня есть этот код:

Public nrSheet As Integer
Public sheetName As Variant

Sub serials()

a = 1
nrSheet = ThisWorkbook.Sheets.Count
For i = 2 To nrSheet
    sheetName = Sheets(i).Name
    a = a + 1
Next
End Sub

, и я хочу иметь что-то вроде

sheetName & a = Sheets (i) .Name

и результат должен быть:

sheetName1 = "Sheet1"

sheetName2 = "Sheet2"

Как это сделать, поскольку не работает с & или +

Спасибо

Ответы [ 3 ]

0 голосов
/ 06 июля 2011

Вы можете использовать «для каждой петли», чтобы пройти через каждый лист.Использование «Scripting.Dictionary» вместо массива может избавить вас от головной боли.

Вот еще один подход для ваших нужд:

Public sheetName As Scripting.Dictionary

Sub serials()
    Dim mySheet As Worksheet

    Set sheetName = New Scripting.Dictionary

    For Each mySheet In ThisWorkbook.Worksheets
        sheetName.Add mySheet.Name, "Here you can add another variable/value" 'Dictionary requiers allways a Key (first argument) and a Item(second argument)
    Next mySheet

    Set sheetName = Nothing 'Put this line at the end of your procedure.
End Sub

Чтобы получить ваши значения, вам нужно только:sheetName.Keys ( п ).Где n - номер индекса.Чтобы проверить, есть ли значение в словаре, просто используйте sheetName.Exists ( Name ).Где Имя - это имя листа.

Чтобы сделать словарь доступным, перейдите в раздел «Дополнительная информация»> «Справочная информация» и установите флажок «Время выполнения сценариев Microsoft».

ЗдесьВы можете получить больше информации о объекте словаря .

0 голосов
/ 06 июля 2011

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

Массивы
Массивы в VB обычно объявляются следующим образом:

Dim sheetName(1 to 10) As String

В приведенном выше примере мы указали, что нам нужны индексы от 1 до 10, поэтому мы можем получить к ним доступ, указав что-то вроде:

Debug.Print sheetName[5]

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

Dim sheetName() As String

А затем вам нужно будет объявить, насколько большим используется элемент:

ReDim sheetName(1 to 10)

Обратите внимание, что если у вас есть массив и вы хотите добавить в него больше элементов, вам нужно будет самостоятельно изменить его размер.
Скажем, у нас есть от 1 до 10 единиц, изатем позже вы захотите увеличить его:

ReDim Preserve sheetName(1 to 20)

Где ключевое слово preserve используется, чтобы убедиться, что мы не потеряем существующие данные.

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

Затем вы можете получить данные массива, выполнив что-то вроде следующего:

Dim sheetName(1 To 10) As String
sheetName(1) = "One"
sheetName(2) = "Two"
Dim i As Integer
For i = 1 To 10
    Debug.Print sheetName(i)
Next i

Обратите внимание, что в этой ситуации мыобъявлено, что будет 10 листов, несмотря на то, что мы объявили только два из них, так что это будет довольно глупо пройти и распечатывать каждое из 10 имен листов, 8 из которых будут пустыми.

Anoздесь можно использовать For Each, поэтому нам не нужно беспокоиться о счетчике.

Dim sheetName(1 To 10) As String
sheetName(1) = "One"
sheetName(2) = "Two"
Dim sheet As Variant
For Each sheet In sheetName
    Debug.Print sheet
Next sheet

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

К счастью, в VB есть некоторые встроенные коллекции, которые устраняют некоторые из этих проблем.

Коллекции
В Visual Basic есть встроенные коллекции.Вы можете объявить коллекцию следующим образом:

Dim sheetName As Collection
Set sheetname = New Collection

Обратите внимание, что здесь нам нужно использовать ключевые слова Set и New для создания коллекции, потому что это сложный тип.
Теперь у вас есть коллекция, котораяВы можете добавить к этому, выполнив следующее:

sheetName.Add "Your Sheet Name"

Продвинув вышеприведенные примеры кода на шаг вперед, мы могли бы сделать следующее:

Dim sheetName As Collection
Set sheetName = New Collection
sheetName.Add "One"
sheetName.Add "Two"
Dim sheet As Variant
For Each sheet In sheetName
    Debug.Print sheet
Next sheet

И теперь, обратите внимание, что мы неНе нужно беспокоиться о количестве элементов в Коллекции.Мы можем добавить к нему столько, сколько захотим, и изменение размера будет обработано.

Доступ к коллекциям также можно получить с помощью индексов, таких как массивы, поэтому мы можем сделать следующее, если вы хотите:

Dim i As Integer
For i = 1 To 2
    Debug.Print sheetName(i)    ' where this is the sheetName Collection
Next i

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

Dim sheetName As Collection
Set sheetName = New Collection
sheetName.Add "One", "Sheet" & "1"    ' Note that I have only separated the
sheetName.Add "Two", "Sheet" & "2"    ' Sheet & the 1 for illustrative purposes.
Dim i As Integer
For i = 1 To 2
    Debug.Print sheetName("Sheet" & i)
Next i

И, наконец, для полноты, CaBieberach упомянул Scripting.Dictionary в своем ответе .

Словарь
Словарь на самом деле не является частью стандартного VB, но может быть легко включен.Чтобы сделать это, нужно включить ссылку на «Среду выполнения сценариев Microsoft», перейдя в Инструменты, Ссылки и Добавление отметки в «Среда выполнения сценариев Microsoft».
Как только вы это сделаете, вы можете создать словарь какследует:

Dim sheetName As Scripting.Dictionary
Set sheetName = New Scripting.Dictionary
sheetName.Add "Sheet" & "1", "One"  ' Note that these are reversed. The Key is first,
sheetName.Add "Sheet" & "2", "Two"  ' the Item is second.
Dim sheet As Variant
For Each sheet In sheetName
    Debug.Print sheet
Next sheet

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

Debug.Print sheetName("Sheet1")

И получить вывод «One»

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

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

0 голосов
/ 06 июля 2011

Вы имели в виду:

sheetName = Sheets(i).Name & a

[править]

Нет, нет, извини. :) То, что вы описываете, невозможно, но вы на самом деле ищете массивы. С массивами у вас может быть переменная, представляющая собой список, очень похожий на коллекцию Sheets, которую вы уже используете.

Итак, вы можете написать:

sheetName(a) = Sheets(i).Name & a

и затем используйте sheetName (1) везде, где вам нужно имя первого листа.

Здесь я нашел учебник по использованию массивов в Excel VBA .

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