2015-10-29 6 views
1

У меня есть функция, которая возвращает мне список текущих листов:Варианта против несоответствия типа Струнного при прохождении массива функционировать

Function getListOfSheetsW() As Variant 
    Dim i As Integer 
    Dim sheetNames() As Variant 

    ReDim sheetNames(1 To Sheets.Count) 
    For i = 1 To Sheets.Count 
    sheetNames(i) = Sheets(i).name 
    Next i 

    getListOfSheetsW = sheetNames 
End Function 

Тогда у меня есть функция, которая возвращает значение TRUE или FALSE в зависимости от того, если needle в haystack или нет ,

Function IsInArray2(ByVal needle As String, haystack() As String) As Boolean 
    Dim element As Variant 
    For Each element In haystack 
    If element = needle Then 
     IsInArray = True 
     Exit Function 
    End If 
    Next element 
    IsInArray = False 
End Function 

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

Sub CreateNewSheet(ByVal dstWSheetName As String) 
    Dim srcWSheetName As String 

    ' Dim sheetNames() As String 
    Dim sheetNames() As Variant 

    sheetNames = getListOfSheetsW() 
    Dim sheetCount As Integer 

    If IsInArray2(dstWSheetName, sheetNames) Then 
    MsgBox "Sheet with following name: " & dstWSheetName & " already exists" 
    Else 
    srcWSheetName = ActiveSheet.name 
    sheetCount = Sheets.Count 

    ' CREATE NEW SHEET 
    ' Worksheets(dstWsheetName).Delete 
    Sheets.Add.name = dstWSheetName 
    ' Q: why 6 instead of 5 
    ' Worksheets("Test").Move after:=Worksheets("Sheet5") 
    Worksheets(dstWSheetName).Move After:=Worksheets(sheetCount + 1) 

    ' SWITCH TO SRC SHEET 
    Worksheets(srcWSheetName).Activate 
    End If 
End Sub 

Я звоню это так:

Sub CallCreateNewSheet() 
    Call CreateNewSheet("test") 
End Sub 

Я думаю, что проблема с Dim sheetNames() As String или Dim sheetNames() As Variant.

Когда я использую Dim sheetNames() As String я получаю

Run-time error '13': Type mismatch

Когда я использую Dim sheetNames() As Variant я получаю:

Compile error: Type mismatch: array or user-defined type expected

У меня была аналогичная проблема, но before определение sheetNames, как массив не помог здесь. В чем проблема и что означают две разные ошибки?

ответ

0

Вы будете избегать всех этих проблем, если вы переключитесь с типизированных массивов на варианты-массивы.

В вашей первой функции, удалите эту строку:

Dim sheetNames() As Variant 

Изменить определение линии вашей 2-ой функции от этого:

Function IsInArray2(ByVal needle As String, haystack() As String) As Boolean 

... к этому:

Function IsInArray2(ByVal needle As String, haystack) As Boolean 

В вашей группе, измените эту строку:

Dim sheetNames() As Variant 

... к этому:

Dim sheetNames 
+0

Спасибо, это сработало. Итак, если я объявил переменную без типа, то тип переменной задается в соответствии с типом переменной, который ей назначен? Я думал, что это цель Варианта. Спасибо –

+0

Добро пожаловать. Если вы не укажете тип, тип по умолчанию будет Variant. –

1

Как насчет новый сценарий, как:

Sub NewSheetByName(SName as String) 
    Dim oldSheet as Object 

    For Each oldSheed in ThisWorkbook.Sheets 
    if oldSheet.Name = Sname Then 
     MsgBox "Sheet with following name: " & SName & " already exists" 
     Exit Sub 
    End If 
    Next 

    oldSheet = ActiveSheet 
    Sheets.Add.Name = SName 
    ActiveSheet.Move , Worksheets(Sheets.Count) 

    oldSheet.Activate 

End Sub 
+0

Спасибо за ваш ответ, я проголосовал за ваш ответ. –

1

переменных должен быть в SINC.

Объявляет таким же образом переменную sheetNames в обеих процедурах:

Sub CreateNewSheet(ByVal dstWSheetName As String) и

Function getListOfSheetsW() As Variant

объявить его как: Dim sheetNames() As String

Также отметим, что Function IsInArray2 всегда возвращает False. Чтобы исправить это, замените IsInArray на IsInArray2 в теле функции.

Это хорошая практика, чтобы всегда иметь

Option Explicit

в начале модулей.

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

Dim Wsh As Worksheet 
On Error Resume Next 
Set Wsh = Workbook(x).Worksheets("Test") 
On Error GoTo 0 
If Wsh Is Nothing Then Add Worksheet 
+0

Спасибо за ответ, я пробовал это, и он дает мне «Невозможно назначить массив» 'error на' sheetNames = getListOfSheetsW() 'line. –

+0

Я только что проверил его, и он сработал ... Вы изменили на 'Dim sheetNames() As String' в обеих процедурах? 'Sub CreateNewSheet (ByVal dstWSheetName As String)' и 'Функция getListOfSheetsW() As Variant' – EEM

+0

Да, теперь он работает, код здесь http://pastebin.com/R6dLLR1g Я должен был сделать что-то не так, возможно, я set 'Функция getListOfSheetsW() As String' вместо' Function getListOfSheetsW() As Variant' –