2017-02-09 5 views
2

Мне нужно просмотреть все рабочие листы в моей книге. Если имя рабочего листа содержит текст «Преимущества», тогда мне нужно запустить макрос на этом листе в качестве активного листа, а затем перейти к следующему.InStr in If If

У меня есть этот код и (1) он запускает макрос в любом случае и (2) он не перебирается к следующему листу.

Я новичок в VBA и не смог понять это.

Sub CheckSheets() 
    Dim sh As Excel.Worksheet 
    For Each sh In ActiveWorkbook.Sheets 
     If InStr(sh.Name, "Benefits") <> 0 Then 
      Call AddCheckBoxesRange 
     End If 
    Next sh 
End Sub 


Sub AddCheckBoxesRange() 
'by Dave Peterson 
'add Form checkboxes 
Dim c As Range 
Dim myCBX As CheckBox 
Dim wks As Worksheet 
Dim rngCB As Range 
Dim strCap As String 

Set wks = ActiveSheet 
Set rngCB = wks.Range("B3:E3") 
'Set rngCB = Selection 
strCap = "Select Plan" 

For Each c In rngCB 
    With c 
    Set myCBX = wks.CheckBoxes.Add _ 
     (Top:=.Top, Width:=.Width, _ 
     Height:=.Height, Left:=.Left) 
    End With 
    With myCBX 
    .Name = "cbx_" & c.Address(0, 0) 
    .LinkedCell = c.Offset(1, 0) _ 
     .Address(external:=True) 
    .Caption = strCap 
' .OnAction = ThisWorkbook.Name _ 
'  & "!mycbxMacro" 
    End With 
Next c 

End Sub 
+1

Измените ваше Если заявление будет 'Если InStr (1, sh.Name, "Преимущества", vbTextCompare)> 0 Тогда 'и трудно сказать, нужны ли какие-либо другие настройки, не видя код для' AddCheckBoxesRange' – tigeravatar

+0

. Как 'AddCheckBoxesRange' знает, какой лист для o влиять на? – barrowc

+1

Короткий ответ: добавьте 'sh.Activate' перед' Call'. Скучный, но правильный ответ: измените свой 'AddCheckBoxesRange', чтобы иметь свой целевой лист в параметре вместо того, чтобы действовать на' ActiveSheet'. –

ответ

1

Без использования Activate (всегда хорошая вещь, чтобы избежать), код должен выглядеть следующим образом:

Sub CheckSheets() 
    Dim sh As Excel.Worksheet 
    'Use the Worksheets object instead of the Sheets object 
    ' so that we don't try to process any Charts 
    For Each sh In ActiveWorkbook.Worksheets 
     If InStr(sh.Name, "Benefits") <> 0 Then 
      'Pass the sh worksheet, and avoid the old Call syntax 
      AddCheckBoxesRange sh 
     End If 
    Next sh 
End Sub 

'Change the subroutine to accept a Worksheet as a parameter 
Sub AddCheckBoxesRange(wks As Worksheet) 
    'by Dave Peterson 
    'add Form checkboxes 
    Dim c As Range 
    Dim myCBX As CheckBox 
    'Don't need to declare wks anymore as it is declared as a parameter 
    'Dim wks As Worksheet 
    Dim rngCB As Range 
    Dim strCap As String 

    'Don't need to set wks anymore as it is passed as a parameter 
    'Set wks = ActiveSheet 
    Set rngCB = wks.Range("B3:E3") 
    'Set rngCB = Selection 
    strCap = "Select Plan" 

    For Each c In rngCB 
     With c 
     Set myCBX = wks.CheckBoxes.Add _ 
      (Top:=.Top, Width:=.Width, _ 
      Height:=.Height, Left:=.Left) 
     End With 
     With myCBX 
     .Name = "cbx_" & c.Address(0, 0) 
     .LinkedCell = c.Offset(1, 0) _ 
      .Address(external:=True) 
     .Caption = strCap 
    ' .OnAction = ThisWorkbook.Name _ 
    '  & "!mycbxMacro" 
     End With 
    Next c 

End Sub 
6
Sub CheckSheets() 
    Dim sh As Excel.Worksheet 
    For Each sh In ActiveWorkbook.Sheets 
     If sh.Name Like "*benefits*" Then 
      Call AddCheckBoxesRange(sh.Name) 
     End If 
    Next sh 
End Sub 


Sub AddCheckBoxesRange(sName) 
    ActiveWorkbook.Sheets(sName).Activate 
    'by Dave Peterson 
    'add Form checkboxes 
    Dim c As Range 
    Dim myCBX As CheckBox 
    Dim wks As Worksheet 
    Dim rngCB As Range 
    Dim strCap As String 

    Set wks = ActiveSheet 
    Set rngCB = wks.Range("B3:E3") 
    'Set rngCB = Selection 
    strCap = "Select Plan" 

    For Each c In rngCB 
     With c 
      Set myCBX = wks.CheckBoxes.Add _ 
       (Top:=.Top, Width:=.Width, _ 
       Height:=.Height, Left:=.Left) 
     End With 
     With myCBX 
      .Name = "cbx_" & c.Address(0, 0) 
      .LinkedCell = c.Offset(1, 0) _ 
      .Address(external:=True) 
      .Caption = strCap 
      '.OnAction = ThisWorkbook.Name _ 
      ' & "!mycbxMacro" 
     End With 
    Next c 
End Sub 
+1

Спасибо. Это работает, и я догадываюсь от @ A.S.H. что это правильный путь, а не короткий путь. Оба работали. Еще раз спасибо. – JordanCA57

+0

@ JordanCA57 да, вот что я имел в виду, всегда лучше не рассчитывать на элементы «ActiveSheet», «ActiveCell» и «Selection». :) –

+0

@RyanL Я думаю, что даже лучше передать лист непосредственно в качестве параметра функции вместо имени. –

3

некоторые незначительные изменения в хороший ответ вы уже получили:

  1. Не нужно активировать рабочие листы во второй части, лучше работать с листом непосредственно
  2. Пропустите сам лист к основным подразделам, а не имя листа
  3. Вы проверяли на Преимущество не приносит пользу так хорошо использовать Lcase$, чтобы убедиться, что вы захватить ваши строки
  4. Используйте Application.ScreenUpdating = False, чтобы выключить Excel, когда он управляет средой (хотя при этом не выбираются листы, в этом случае будет устранена большая часть экрана).

вызова подменю

Sub CheckSheets() 
    Dim sh As Worksheet 
    Application.ScreenUpdating = False 
    For Each sh In ActiveWorkbook.Sheets 
     If LCase$(sh.Name) Like "*benefits*" Then Call AddCheckBoxesRange(sh) 
    Next sh 
    Application.ScreenUpdating = True 
End Sub 

основной суб

Sub AddCheckBoxesRange(ws As Worksheet) 

    'by Dave Peterson 
    'add Form checkboxes 
    Dim c As Range 
    Dim myCBX As CheckBox 
    Dim rngCB As Range 
    Dim strCap As String 


    Set rngCB = ws.Range("B3:E3") 
    'Set rngCB = Selection 
    strCap = "Select Plan" 

    For Each c In rngCB 
     With c 
      Set myCBX = ws.CheckBoxes.Add _ 
       (Top:=.Top, Width:=.Width, _ 
       Height:=.Height, Left:=.Left) 
     End With 
     With myCBX 
      .Name = "cbx_" & c.Address(0, 0) 
      .LinkedCell = c.Offset(1, 0) _ 
      .Address(external:=True) 
      .Caption = strCap 
     End With 
    Next c 
End Sub