Переменная используется в другом модуле VBA - PullRequest
0 голосов
/ 31 марта 2020

Я очень плохо знаком с VBA и мне нужна вся помощь, которую я могу получить. Модуль 1 подсчитывает количество ячеек с целыми числами в первой строке, начиная с C1 (A1 и B1 - заголовки) в «LLP Dis c Sheet». Число ячеек для этого рабочего листа c равно 9. Однако 9 не всегда число. Иногда число составляет 1, 2, 3, 4 и т. Д. c. Это просто зависит, заполняет ли пользователь эти ячейки. Я пытаюсь сохранить это число 9 для использования в Модуле 2.

Модуль 2 производит копии всего листа под названием «MasterCalculator», который я планирую переименовать на каждом листе, произведенном в значения Ячейки, которые были подсчитаны в Модуль 1. Количество произведенных копий должно соответствовать расчету в Модуле 1 (который в настоящее время равен 9).

Я не могу понять, как ссылаться на переменную 'l c' в модуле t3 () в модуле test (). Количество копий листа MasterCalculator является неточным.

МОДУЛЬ 1

Public lc As Integer
Sub t3()
Dim lc As Long, sh As Worksheet
Set sh = ActiveSheet
With sh

lc = Rows(1).SpecialCells(xlCellTypeConstants, 23).Cells.Count - 1
End With
ThisWorkbook.Save
End Sub

МОДУЛЬ 2

Sub test()
Dim sh As Worksheet
Dim last_is_visible As Boolean

With ActiveWorkbook
last_is_visible = .Sheets(.Sheets.Count).Visible
.Sheets(Sheets.Count).Visible = True
.Sheets("MasterCalculator").Copy After:=.Sheets(Sheets.Count)
Set sh = .Sheets(Sheets.Count)
If Not last_is_visible Then .Sheets(Sheets.Count - t3.lc).Visible =     False
sh.Move After:=.Sheets("LLP Disc Sheet")
End With
End Sub

Ответы [ 2 ]

2 голосов
/ 31 марта 2020

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

Во-вторых, ваша строка lc = Rows(1).SpecialCells(xlCellTypeConstants, 23).Cells.Count выдаст ошибку, если нет соответствующих SpecialCells. Поэтому для этого потребуется обработчик ошибок, чтобы он мог возвращать -1 вместо сбоя.

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

Function ColumnsCount(Optional Ws As Worksheet) As Long

    If Ws Is Nothing Then Set Ws = ActiveSheet
    With Ws
        ColumnsCount = .Cells(1, .Columns.Count).End(xlToLeft).Column - 1
    End With
End Function

Реализация этой функции в вашем коде приводит к этим двум строкам кода в вашей Test процедуре.

Set Sh = .Sheets(Sheets.Count)
If Not last_is_visible Then .Sheets(Sh.Index - ColumnsCount(Sh)).Visible = False

Функция ColumnCount вернет счет из рабочего листа, заданного ему в качестве параметра. В приведенном выше коде это лист Sh. В коде вашего вопроса это, кажется, ActiveSheet (возможно, Sh - это активный лист. Просто убедитесь, что вы пропустили лист, на который хотите сосчитать, и функция вернет правильный число.

В качестве двух принципиальных вопросов: во-первых, избегайте максимально возможного использования ActiveSheet. Присвойте свои листы переменным с осмысленным именем и обращайтесь к ним по именам, которые вы дали себе. Это потому, что ActiveSheet может зависеть от действий пользователя, выходящих за рамки вашего кода, и 9 раз из 10 это не значимое имя.

Во-вторых, избегайте того, что rubberduck называет «snake_names». LastIsVisible - это значимое имя, last_is_visible - это боль в глазу. Я бы использовал LastVis, потому что он короче. Я также рекомендую использовать прописные и строчные буквы в именах, и это моя причина.

  1. Когда вы объявляете имена, в операторах Dim , используйте заглавные и маленькие буквы.
  2. При написании кода используйте только строчные буквы.
  3. VBA исправит заглавные буквы вы печатаете, чтобы соответствовать объявлению.
  4. Итак, когда VBA не меняет введенные вами имена, вы знаете, что существует опечатка. - Мгновенное оповещение без каких-либо усилий. И ваш код становится легче читать в сделке.
1 голос
/ 31 марта 2020

Для меня предпочтительнее установить Function:

Function Lc(Optional sh As Worksheet) As Long
    If sh Is Nothing Then Set sh = ActiveSheet
    With sh
        Lc = .Rows(1).SpecialCells(xlCellTypeConstants, 23).Cells.Count - 1
    End With
End Function

и вызывать его всякий раз, когда вам нужно, например:

Sub test()
    Dim sh As Worksheet
    Dim last_is_visible As Boolean

    With ActiveWorkbook
        last_is_visible = .Sheets(.Sheets.Count).Visible
        .Sheets(Sheets.Count).Visible = True
        .Sheets("MasterCalculator").Copy After:=.Sheets(Sheets.Count)
        Set sh = .Sheets(Sheets.Count)
        If Not last_is_visible Then .Sheets(Sheets.Count - Lc).Visible = False '<--- Lc will get the "current" Lc value
        sh.Move After:=.Sheets("LLP Disc Sheet")
    End With
End Sub

Переменная Public имеет вид Это может быть опасно:

  • «следуйте» ему по всему вашему коду и убедитесь, что он не установлен неохотно

  • проверить, что он не сохраняется во время сеансов

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