微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

VBA 公共变量不起作用 - MS Word - 计算表中的字符

如何解决VBA 公共变量不起作用 - MS Word - 计算表中的字符

主要的 VBA 过程计算 Word 文档中表格单元格中的字符数。因为它可以用不同的方式计算字符:

  • 计算所选表格的“目标”文本
  • 计算所选表格的“完成”文本
  • 计算每个表中的 Obj 和 Acc 文本(循环),对于所有表(另一个循环)

我为上面调用主过程的每个选项创建了调用过程。通过这种方式,我将变量从调用 Sub 传递到主 Sub。这些变量 (1) 告诉主 Sub 是否要计算第 3 行(目标)或第 5 行(成就)或两者中的内容,以及 (2) 在主 Sub 中输入 If/then 行以确保计算右行。 事后看来,当时它看起来很优雅 - 不是那么优雅。

Word模板如下:

word template

O1 中会有文本,VBA 会对其进行计数(字符、空格 + 段落)并在 C1 中输出,如果超过/低于字符限制,C1 填充会变为红色或绿色。对于以下任意数量的表格,A1 和 C2 都是相同的。

问题描述
当我将行/列硬编码到代码中的各个位置时,VBA 正在为上述操作工作。如果从表中添加/删除行/列,它们将不得不在多个位置更新。如果行/列号在一个地方并被称为变量会更简单,所以我将行/列#s 更改为公共变量。然后问题就开始了。

代码中,我跟踪 (debug.print) oRow输出行)和 chcct(字符数列)的变化,并且在主要 Sub 运行时两者都是 0,尽管两者都是在下面的公共 Sub Row_Col_Num() 中初始化为 3。

我的公共变量位于第一个 Sub() 之前的模块顶部,并表示为 Public。包含变量赋值的 Sub Row_Col_Num() 也是 Public。所有 Sub 都在同一个标​​准模块中。

Option Explicit

 Public oRow As Integer      'row with "Objectives" text
 Public aRow As Integer      'row with "Accomplishments" text
 Public cOnA As Integer      'column that both obj and accmp text are in
 Public cChCt As Integer     'column that the char count is output to

Public Sub Row_Col_Num()
    oRow = 3
    aRow = 5
    cOnA = 1
    cChCt = 3
Debug.Print "cchct pub sub: " & cChCt
End Sub

尝试解决问题和结果

  1. 我通常使用变量并将其保留为 Public 以及分配变量 (oRow =3) 值的 Sub。
Sub TableCharCount_Obj()
'Run character count for the "Objectives"  in the SELECTED table
Debug.Print "orow = " & oRow
Call TableCharCount(oRow,oRow)   'provide it 2x to make IF and FOR loop
End Sub
  1. 我尝试在使用变量时将 Sub() 名称放在变量前面,例如Row_Col_Num.orow,在上面的 Sub 中。
    Call TableCharCount(Row_Col_Num.oRow,Row_Col_Num.oRow)

  2. 我也尝试了变量前面的模块名称,例如Module1.orow。 Call TableCharCount(Module1.oRow,Module1.oRow)

结果
#1 & #3 导致宏计算错误的行并输出错误的单元格。
#2 导致错误“预期函数或变量”在行:Call TableCharCount(Row_Col_Num.oRow,Row_Col_Num.oRow)
所有 3 个案例 orowcchct 在整个运行过程中都继续为 0。

问题/解决方
a) 是否可以将公共变量 (oRow) 用作从调用 Sub 传递给被调用 Sub 的参数 ByVal a As Integer

b) 为公共变量赋值的 Public Sub Row_Col_Num() 是否必须显式运行或调用以使用正确的值填充其他 Sub 中的变量?

c) 在调用主 Sub 之前,我应该在每次调用 Sub 中调用 Public Sub Row_Col_Num() 吗?

Sub TableCharCount_Obj()
Call Public Sub Row_Col_Num()  '<<< add this call
Call TableCharCount(oRow,oRow)   'provide it 2x to make IF and FOR loop
End Sub

这个选项看起来很糟糕。

如果不是很明显,我添加了更多功能时会出现一些任务蠕变现在,如果我可以让公共变量工作,它就会完成。感谢任何使这些变量起作用的建议。对于这个问题,我只留下了变量 Sub、第一个调用 Sub 和主 Sub 的代码。下面的 VBA:

'#0 -- This creates variables for column and row number used in all the macros.  Only need to change row/col number here if row/col are added/deleted  

Option Explicit

Public oRow As Integer      'row with "Objectives" text   
Public aRow As Integer      'row with "Accomplishments" text   
Public cOnA As Integer      'column that both obj and accmp text are in   
Public cChCt As Integer     'column that the char count is output to

'This assigns row/column numbers to the variables
Public Sub Row_Col_Num()
    oRow = 3
    aRow = 5
    cOnA = 1
    cChCt = 3  
Debug.Print "cchct pub sub: " & cChCt End Sub

'#2  
Sub TableCharCount_Obj() 'Run character count for the "Objectives" in the SELECTED table  
Debug.Print "orow = " & oRow  
Call TableCharCount(oRow,oRow)   'provide it 2x to make IF and FOR loop  
End Sub  

'other calling procedures removed

'#5  
Option Explicit  
Sub TableCharCount(ByVal a As Integer,ByVal b As Integer)  
'Counts total characters in a cell w/in a table and outputs the number to a different cell,and colors the cell red or green if over/under the maximum number of characters.

Dim charCount,charWSCount,paraCount,charTot As Double  
Dim iRng,oRng,txtRng As Word.Range  
Dim i,max,s,t,x As Integer  
Dim tcount,tbl As Integer  
Dim DocT As Table           'for active doc tables

Debug.Print "cchct1= " & cChCt 'Debug.Print vbCr & "-----START-------" & vbCr Application.ScreenUpdating = False

If a <> b Then
    tcount = ActiveDocument.Tables.Count
    tbl = 1                 'used in FOR loop,start w/ table #1
    s = b - a     '"STEP" used in FOR loop = # of rows between objectives text and accomplishments text Else
    On Error GoTo ErrMsg    'handles expected user error of not selecting a table to execute on
    tbl = ActiveDocument.Range(0,Selection.Tables(1).Range.End).Tables.Count       'ID the table that is selected
    tcount = tbl            'prevents FOR loop from trying to run again
    s = 1    '"STEP" used in FOR loop = # of rows between objectives text and accomplishments text / do not set to zero = infinite loop End If

'Debug.Print "# of Tables: " & tcount

For t = tbl To tcount                       'loops thru the tables
    Set DocT = ActiveDocument.Tables(t)
    For x = a To b Step s                   'loops thru the applicable row(s) in the table
            'Debug.Print "x @ start = " & x
            'Debug.Print "table " & t
            iRng = DocT.Cell(x,cOnA)
            iRng.Select
      
        'Count used in output
            Selection.MoveLeft wdCharacter,1,wdExtend     'computerstats requires the text itself selected,characters.count can use the whole cell selected
            charWSCount = Selection.Range.ComputeStatistics(Statistic:=wdStatisticCharactersWithSpaces) 'counts bullets & space after bullet / not line breaks (paragraphs)
            'Debug.Print "Comp statchar#  " & charWSCount
        '---------
            paraCount = Selection.Range.ComputeStatistics(Statistic:=wdStatisticParagraphs)
            'Debug.Print "#paras = " & paraCount             
        '----------
            charTot = charWSCount + paraCount
                
        'Output to table cell
            i = x - 1                           'output cell is 1 row above cell that is counted
            Set oRng = DocT.Cell(i,cChCt).Range    'Char count ouput row,column
    Debug.Print "cchct2= " & cChCt
            
            oRng.Text = charTot
            Set txtRng = DocT.Cell(i,cChCt - 1).Range    '"# Char:" location row,column
            txtRng.Text = "# Char:"
            
        
        'Maximum # of char allowed in a cell.  Used to change cell fill red or green.
            max = 2000                              '"Accomplishment" row (row 5) has a max of 2000
            If i = 2 Then max = 1500                '"Objective" row (row 3) has a max of 1500
        
        'Change color of cell to indicate over/under max # of characters
            If charCount < max Then
                oRng.Shading.BackgroundPatternColor = wdColorBrightGreen
                Else: oRng.Shading.BackgroundPatternColor = wdColorRed
            End If
            
            'Debug.Print "x @ end = " & x
            'Debug.Print "--------Next x--------------"
        
    Next x
    
    'Debug.Print "------Next Table------"

Next t

ActiveDocument.Tables(tbl).Select       'attempt to move to top of 1st table if using CharCount_AllTab() or just to the top of the selected table for the other macros  
Selection.GoTo What:=wdGoToBookmark,Name:="\Page" Selection.StartOf

Application.ScreenUpdating = True  
Exit Sub

ErrMsg: MsgBox "Select a table by placing the cursor anywhere in the table.  Press OK and try the macro again numnuts!",_
    vbOKOnly,"Table not selected"  
End Sub

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。