任务
我的目的是使用数据字段方法以最有效的方式将UserForm列表框数据写回到工作表范围。
基本方法(尤其是使用数据范围)
AFAIK是将数据写入范围的最有效方法是使用数组。如果数据来自一个范围,那么它最好使用数据字段数组,默认情况下是二维(一个基于数组)并允许 a)从工作表到数组获取数据 b)将数组写回到表格 一个代码行:
Dim v ' As Variant
Dim rng As Range
Set rng = ...
' a) range to array
v = rng.Value
' b) array to range
rng.Value = v
使用ListBox数据数组时的差异
ListBox数据存储在2dim中,但基于零的数组,例如的 ListBox1.List
[提示:因此,可以使用预定义的数组创建项目,而不是使用通常已知的Add方法,BTW仅限于10列(索引为0到9)。 ]
尽管存在这种差异,但可以读入ListBox数据并使用所描述的基本方法将它们写回工作表:
' aa) ListBox data to array
v = Me.ListBox1.List
' bb) array to range
rng.Value = v
此外,我注意到默认情况下,数组列数为10,因此这不会对应于以编程方式设置的ColumnCount。因此,有必要调整检查阵列尺寸的范围,参见代码示例中的调试协议。
问题和解决方法
如果存在具有前导" =="的项目,则将数据字段数组写回到单个内容中的工作表会引发错误1004(应用程序定义的错误或对象定义的错误)。字符串或类似的用户输入,因为Excel无法正确解释。
我尝试使用
rng.Text = v
而不是
rng.value = v
也失败了,导致424对象需要出错。
问题 ==>是否可以使用前导" ="来纠正潜在的错误项目?字符没有循环使用VBA或API方法通过所有数组项?欢迎任何代码示例替换我的工作(代码中的第3步)
我的代码
我的代码包含四个步骤 1)创建一个2dim数据字段数组(v) 2)设定目标范围(rng) 3)[我在纠正每个数组项目的工作] 4)将数据写回工作表
Private Sub CommandButton1_Click()
' declare variables
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Dump")
Dim s As String ' range address string
Dim sTest As String ' item test string
Dim v As Variant ' data field array
Dim rng As Range ' (target) range
Dim i As Long ' rows counter
Dim j As Long ' columns counter
Dim R As Long ' number of rows
Dim C As Integer ' number of columns
Dim lbxR As Long ' actual number of listbox items in data field
Dim lbxC As Integer ' actual number of listbox columns in data field
' Error Handler
On Error GoTo OOPS
' get programmatically defined listbox dimension
R = Me.ListBox1.ListCount
C = Me.ListBox1.ColumnCount
' clear sheet lines A2:A{r}
ws.Range(ws.Cells(2, 1), ws.Cells(R, C)).value = ""
' ===============================
' 1) create 2dim data field array
' -------------------------------
v = Me.ListBox1.List
' -------------------------------
' 2) set target range (rng)
' -------------------------------
' get actual data field dimension
lbxR = UBound(v, 1) - LBound(v, 1) + 1 ' first dimension
lbxC = UBound(v, 2) - LBound(v, 2) + 1 ' second dimension
s = ws.Range("A2").Resize(lbxR, lbxC).Address
' set correconding target range
Set rng = ws.Range(s) ' target range
' create short protocol - columns by default differ from user defined ColumnCount property !
Debug.Print String(80, "-")
Debug.Print vbNewLine & "** ListBox1 Defs Data Field Array Dimension **"
Debug.Print " [Target Range " & s & "]"
Debug.Print String(80, "-")
Debug.Print " ListCount = " & ListBox1.ListCount, "rows = " & lbxR & " = ubound(v,1)-lbound(v,1)+1 = " & UBound(v, 1) & " - " & LBound(v, 1) & " + 1 "
Debug.Print " ColumnCount= " & ListBox1.ColumnCount, "cols = " & lbxC & " = ubound(v,2)-lbound(v,2)+1 = " & UBound(v, 2) & " - " & LBound(v, 2) & " + 1 "
Debug.Print String(80, "-")
' ----------------------------------------------------------------
' 3) Work around - correct leading "=", if any occurences presumed
' (avoid error 1004 - App-defined or object-defined error)
' ----------------------------------------------------------------
' ==> Is there an alternative way?
' For i = 0 To R - 1 ' edited thx to D.Lee
' For j = 0 To C - 1
' v(i, j) = IIf(Left(Me.ListBox1.List(i, j) & "", 1) = "=", " ", "") & _
' Me.ListBox1.List(i, j)
' Next j
' Next i
' -------------------------------
' 4) write data back to worksheet
' -------------------------------
rng.value = v
Exit Sub
' =============
' Error Handler
' =============
OOPS:
MsgBox "ERL=" & Erl & " |Error " & Err.Number & "|" & Err.Description & vbNewLine & _
"s=" & s, vbExclamation
End Sub
提示我建议您阅读"Arrays and Ranges in VBA" by C.Pearson
自9月17日起对OP的补充(替代解决方案)
如果你知道第一个目标列是纯文本的,你可以在第[4]节之前编写以下语句,而不是搜索以=
开头的每个列表项:
rng.Columns(1).NumberFormat = "@"
答案 0 :(得分:1)
Lbound(v,1)= 0 ubound(v,1)= r-1 所以,它需要修改i和j。
For i = 0 To R - 1
For j = 0 To C - 1
v(i, j) = IIf(Left(Me.ListBox1.List(i, j) & "", 1) = "=", " ", "") & _
Me.ListBox1.List(i, j)
Next j
Next i