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