如何将用户输入(字符串变量)转换为Excel表格引用

如何将用户输入(字符串变量)转换为Excel表格引用,excel,vba,Excel,Vba,我有一个复杂的Excel 2016股票和期权交易应用程序,但只是一个简单的问题,答案并不十分明显。市场收盘后,交易员将被提示输入包含当日交易的电子表格的名称,该电子表格存储在Excel表格中,每笔交易一行 问题:如何将用户输入(例如字符串变量“Mar06”)转换为名称管理器中列出的Excel表格名称tblMar06,应用程序可以使用该名称使用结构化表格引用执行统计,而无需多个数组或列表对象或VLOOKUP(…,间接)语句 简单的例子: 使用否错误测试工作表名称的无效条目 并对该工作表上的无效

我有一个复杂的Excel 2016股票和期权交易应用程序,但只是一个简单的问题,答案并不十分明显。市场收盘后,交易员将被提示输入包含当日交易的电子表格的名称,该电子表格存储在Excel表格中,每笔交易一行

问题:如何将用户输入(例如字符串变量“Mar06”)转换为名称管理器中列出的Excel表格名称tblMar06,应用程序可以使用该名称使用结构化表格引用执行统计,而无需多个数组或列表对象或VLOOKUP(…,间接)语句

简单的例子:

  • 使用错误测试工作表名称的无效条目
  • 并对该工作表上的无效表项进行NO错误测试
如果工作表名称或表格名称无效,则在将LO设置为所需表格的函数中会出现
下标超出范围的错误

关于公式和Excel类型的结构化引用,您将遇到一些问题

Excel公式无法写入其他单元格。因此,即使使用
Evaluate
方法,您仍然需要捕获
IF
语句的结果,然后将其写到工作表中所需的位置

这是可行的,但在我看来,这比仅仅使用原生VBA函数更复杂

此外,如果速度成了问题,您可以很容易地调整本机VBA方法,使其读/写VBA数组,而不是读/写工作表,从而显著提高速度

可读性可能是一个问题,但下面是一个示例,说明重新编写公式以使用本机VBA函数,但仍保留表的有用名称:

请注意,下面公式中的
成本
因子将返回零,因为我不清楚您在哪里获得应用于示例中第一个和最后一个项目的成本


我为上述问题设计了一个简单的解决方案,使我能够继续使用结构化Excel表引用,并使用通用表名,例如tblTrades,它对所有工作表都保持不变

...  
Dim ws As Worksheet, tbl As ListObject, sWS As String, sTbl As String, _ 
    tblSave As ListObject
...          
'User inputs the current spreadsheet name, e.g. Mar06  
...  
sWS = "Mar06"    
sTbl = "tbl" & sWS 'current trades table name, e.g. tblMar06  
Set ws = ThisWorkbook.Sheets(sWS)  
ws.Activate  
set tbl =wsListObjects(sTbl)  
Set tblSave = tbl    
tbl.Name = "tblTrades" 'rename table
...      
If ([tblTrades[@Type]] = "Opt") And ([tblTrades[@Action]] = "SLD") Then  
    [tblTrades[@[Realized P&L]]] = [tblTrades[@Qty]] * 100 * _
    [tblTrades[@Price]] - [tblTrades[@Comm]] - Cost  
    'where Cost comes from a previous day's buy  
Else  
    ...  
End If  
tblSave.Name = sTbl 'restore table name to tblMar06  
...

评论不用于扩展讨论;这段对话已经结束。
Option Explicit
Function myTbl(wsName As String) As ListObject
    Set myTbl = ThisWorkbook.Worksheets(wsName).ListObjects("tbl" & wsName)
End Function

Sub tester()
    Dim LO As ListObject
Set LO = myTbl(Application.InputBox("Sheet Name: ", , , , , , , 2))

Stop

'Do your calculations

End Sub
Sub terfuge()
    Dim LO As ListObject
    Dim I As Long

Set LO = myTbl(InputBox("Worksheet Name: "))
With LO.ListColumns
    For I = 1 To LO.DataBodyRange.Rows.Count
       If .Item("Type").DataBodyRange(I) = "Opt" And _
          .Item("Action").DataBodyRange(I) = "SLD" Then

            .Item("Realized P&L").DataBodyRange(I) = _
                .Item("Qty").DataBodyRange(I) * 100 * _
                .Item("Price").DataBodyRange(I) - _
                .Item("Comm").DataBodyRange(I) - _
                .Item("Cost").DataBodyRange(I)
        End If
    Next I
End With

End Sub

...  
Dim ws As Worksheet, tbl As ListObject, sWS As String, sTbl As String, _ 
    tblSave As ListObject
...          
'User inputs the current spreadsheet name, e.g. Mar06  
...  
sWS = "Mar06"    
sTbl = "tbl" & sWS 'current trades table name, e.g. tblMar06  
Set ws = ThisWorkbook.Sheets(sWS)  
ws.Activate  
set tbl =wsListObjects(sTbl)  
Set tblSave = tbl    
tbl.Name = "tblTrades" 'rename table
...      
If ([tblTrades[@Type]] = "Opt") And ([tblTrades[@Action]] = "SLD") Then  
    [tblTrades[@[Realized P&L]]] = [tblTrades[@Qty]] * 100 * _
    [tblTrades[@Price]] - [tblTrades[@Comm]] - Cost  
    'where Cost comes from a previous day's buy  
Else  
    ...  
End If  
tblSave.Name = sTbl 'restore table name to tblMar06  
...