excel activex命令按钮

excel activex命令按钮,excel,activex,Excel,Activex,我有一个电子表格模型,我经常需要扫描输入参数。 我以前使用Excel的内置表函数,但这给我带来了问题,所以现在我只使用一些VBA代码手动进行扫描。 VBA代码运行一个循环,在其中更改输入参数、调用应用程序、计算、存储结果并重复 我发现,如果从窗体控件按钮运行此宏,它可以正常工作。 但是,如果我从ActiveX命令按钮运行宏,它有时只能正常工作。基本上,如果我在点击按钮后根本不移动鼠标,宏运行正常。但是如果我在循环完成之前移动鼠标,那么从那时起,结果将是错误的。 我可以在工作表上使用任意版本的按钮

我有一个电子表格模型,我经常需要扫描输入参数。 我以前使用Excel的内置表函数,但这给我带来了问题,所以现在我只使用一些VBA代码手动进行扫描。 VBA代码运行一个循环,在其中更改输入参数、调用应用程序、计算、存储结果并重复

我发现,如果从窗体控件按钮运行此宏,它可以正常工作。 但是,如果我从ActiveX命令按钮运行宏,它有时只能正常工作。基本上,如果我在点击按钮后根本不移动鼠标,宏运行正常。但是如果我在循环完成之前移动鼠标,那么从那时起,结果将是错误的。 我可以在工作表上使用任意版本的按钮,但是如果我想在用户窗体上使用按钮,我需要使用ActiveX变体。但是当循环运行时,我不能移动鼠标

是否有其他人遇到过此问题并找到了解决方法

这是我从网络上获得的宏,并稍作修改:

Sub IterateTables()
“用于快速计算二维假设数据表的概念验证代码。”版权所有查尔斯·威廉姆斯,决策模型2015年12月16日

Dim rngTable As Range
Dim rngRowCell As Range     'input variable cell location
Dim rngColCell As Range     'input variable cell location
Dim rngFormula As Range     'formula cell at top-left

Dim varRowSet As Variant    'set of input data on top row. 1D vector
Dim varColSet As Variant    'set of input data on left column. 1D vector
Dim varResults() As Variant 'Why parenthesis? Expect an 2D array? Why no parens for two above?

Dim nRows As Long
Dim nCols As Long
Dim j As Long
Dim k As Long

Dim varStartRowVal As Variant   'Initial value
Dim varStartColVal As Variant   'Iniitial value
Dim varFirstVal As Variant      'Initial value

Dim lCalcMode As Long
Dim blCalculated As Boolean
Dim dTime As Double
'
' get the location of what-if table and its formula cell
'Set rngTable = ActiveCell.CurrentRegion    ' expand active cell to the current region
Set rngTable = Sheets("Sheet1").Range("E7:H12")
Set rngFormula = rngTable.Cells(1, 1)   ' Top-Left corner
nRows = rngTable.Rows.Count - 1         ' number of rows in the Column of what-if values
nCols = rngTable.Columns.Count - 1      ' number of columns in the row of what-if values
'
' get the row and column input cells using RefEdit on userform
'With ufIterTable
 '   .RefEditRow.Value = ""
  '  .RefEditCol.Value = ""
   ' .Show                   'Modal or non-modal userform?   ShowModal = True
    'If ufIterTable.RefEditRow.Value <> "" Then Set rngRowCell = Range(.RefEditRow.Value)
    'If ufIterTable.RefEditCol.Value <> "" Then Set rngColCell = Range(.RefEditCol.Value)
'End With

'HArd code insted of userform selection
Set rngRowCell = Range("F3")
Set rngColCell = Range("G3")

' if 2-D and we have got the row and column cells then proceed
If nRows > 0 And nCols > 0 And Not rngRowCell Is Nothing And Not rngColCell Is Nothing Then
    dTime = MicroTimer  'Start timer
    '
    ' create output results array
    ReDim varResults(1 To nRows, 1 To nCols)
    '
    ' get row and column arrays of what-if values
    varRowSet = rngFormula.Offset(0, 1).Resize(1, nCols).Value2
    varColSet = rngFormula.Offset(1, 0).Resize(nRows, 1).Value2
    '
    ' set environment
    Application.ScreenUpdating = False
    lCalcMode = Application.Calculation
    If Application.Calculation <> xlCalculationManual Then Application.Calculation = xlCalculationManual
    '
    ' can only skip initial values if workbook is calculated at start
    If Application.CalculationState = xlDone Then
        blCalculated = True
    Else
        blCalculated = False
    End If
    '
    ' Record initial start values for use at end
    varStartRowVal = rngRowCell.Value2
    varStartColVal = rngColCell.Value2
    varFirstVal = rngFormula.Value2
    '
    ' calculate result for each what-if values pair
    For j = 1 To nRows
        For k = 1 To nCols
            If blCalculated And varRowSet(1, k) = varStartRowVal And varColSet(j, 1) = varStartColVal Then
                '
                ' if what-if value pair is the same as the start values then skip recalc
                 varResults(j, k) = varFirstVal
            Else
                Application.StatusBar = "What-If Table Row " & j & " Column " & k       ' show calc status in the status bar
                '
                ' set values for this iteration, recalc, store result
                rngRowCell.Value2 = varRowSet(1, k)
                rngColCell.Value2 = varColSet(j, 1)
                Application.Calculate                   'Full calculate?
                varResults(j, k) = rngFormula.Value2
            End If
        Next k
    Next j
    '
    ' reset status bar
    Application.StatusBar = False
    '
    ' put results back to sheet
    rngFormula.Offset(1, 1).Resize(nRows, nCols) = varResults       'Write results array to sheet
    '
    ' reset both input cells back to initial values & recalc
    rngRowCell.Value2 = varStartRowVal
    rngColCell.Value2 = varStartColVal
    Application.Calculation = lCalcMode
    Application.Calculate
    '
    ' timer message
    dTime = Int((MicroTimer - dTime) * 1000) / 1000     'End timer
    MsgBox "Time for " & nRows * nCols & " Iterations: " & dTime & " Seconds"
End If
Dim rngTable As Range
“将单元格作为范围”输入变量单元格位置
Dim rngColCell作为“范围”输入变量单元格位置
作为左上角“范围”公式单元格的Dim RNG公式
将varRowSet作为变量设置在顶行上的输入数据集。一维向量
将varColSet作为变量设置在左列的输入数据集。一维向量
Dim varResults()作为变量“为什么使用括号?”?需要2D阵列吗?为什么上面两个人都没有父母?
暗淡的nRows尽可能长
长的
Dim j尽可能长
暗k一样长
作为变量“初始值”的Dim varStartRowVal
Dim varStartColVal作为初始值中的变量
Dim varFirstVal作为变量的初始值
Dim lCalcMode尽可能长
按布尔值计算
双精度数字时间
'
'获取假设条件表及其公式单元格的位置
“Set rngTable=ActiveCell.CurrentRegion”将活动单元格扩展到当前区域
设置rngTable=板材(“板材1”)。范围(“E7:H12”)
设置rngFormula=rngTable.Cells(1,1)的左上角
nRows=rngTable.Rows.Count-1'假设值列中的行数
nCols=rngTable.Columns.Count-1“假设值行中的列数
'
'使用userform上的RefEdit获取行和列输入单元格
“难以忍受
'.RefEditRow.Value=“”
'.RefEditCol.Value=“”
“.Show”模式用户窗体还是非模式用户窗体?ShowModal=True
'如果为ufIterTable.RefEditRow.Value“”,则设置rngRowCell=Range(.RefEditRow.Value)
“如果ufIterTable.RefEditCol.Value为“”,则设置rngColCell=Range(.RefEditCol.Value)
"以
'硬代码代替用户表单选择
设置rngRowCell=范围(“F3”)
设置rngColCell=范围(“G3”)
'如果2-D,我们得到了行和列单元格,然后继续
如果nRows>0且nCols>0且非rngRowCell为空且非rngColCell为空,则
dTime=微定时器的启动定时器
'
'创建输出结果数组
ReDim varResults(1到nRows,1到nCols)
'
'获取假设值的行和列数组
varRowSet=rngFormula.Offset(0,1)。调整大小(1,nCols)。值2
varColSet=rngFormula.Offset(1,0).调整大小(nRows,1).值2
'
"设置环境",
Application.ScreenUpdating=False
lCalcMode=应用程序。计算
如果是Application.Calculation xlCalculationManual,则Application.Calculation=xlCalculationManual
'
'如果工作簿是在开始时计算的,则只能跳过初始值
如果Application.CalculationState=xlDone,则
blcomputed=True
其他的
blCalculated=False
如果结束
'
'记录初始开始值,以便在结束时使用
varStartRowVal=rngRowCell.Value2
varStartColVal=rngColCell.Value2
varFirstVal=rngFormula.Value2
'
'计算每个假设值对的结果
对于j=1至nRows
对于k=1到ncol
如果BLComputed和varRowSet(1,k)=varStartRowVal和varColSet(j,1)=varStartColVal,则
'
'如果假设值对与起始值相同,则跳过recalc
varResults(j,k)=varFirstVal
其他的
Application.StatusBar=“假设表格行”&j&“列”&k”在状态栏中显示计算状态
'
'为此迭代、recalc和存储结果设置值
rngRowCell.Value2=varRowSet(1,k)
rngColCell.Value2=varColSet(j,1)
应用程序。计算“全部计算”?
varResults(j,k)=rng公式值2
如果结束
下一个k
下一个j
'
'重置状态栏
Application.StatusBar=False
'
“把结果放回到纸上
rngFormula.Offset(1,1).Resize(nRows,nCols)=varResults将结果数组写入工作表
'
'将两个输入单元重置回初始值并重新校准
rngRowCell.Value2=varStartRowVal
rngColCell.Value2=varStartColVal
Application.Calculation=lCalcMode
应用。计算
'
'计时器消息
dTime=Int((微定时器-dTime)*1000)/1000'结束定时器
MsgBox“时间”&nRows*nCols&“迭代次数:&dTime&“秒”
如果结束

结束Sub

欢迎来到StackOverflow,John。为了帮助您,我们需要更多信息和(至少)可能无法正常工作的VBA代码。因此,请输入并包含您编写的VBA代码。对我来说,这听起来很像那里可能有一些
ActiveCell
(或类似的)引用,当你移动光标时,或者甚至在代码运行时敢在另一个工作表或文件上激活(单击)时,这些引用很容易把事情搞砸。感谢代码更新。正如我所认为的,这段代码中有一些非限定引用,很可能会导致不必要的行为。例如