【发布时间】:2019-01-11 13:23:26
【问题描述】:
我有一个包含文本框和命令按钮的 Excel 2016 用户表单。我希望能够在文本框中键入一个或多个名称,并让用户窗体在检查重复项后将它们添加到命名范围。如果名称已经在命名范围内,我希望将该名称添加到我的 MsgAdd 字符串并继续到文本框的下一行(如果应用)。
***新尝试: 这是我第一次尝试使用字典。当我尝试使用 .Add 而不是 .Item 时,我收到一条错误消息,说明该值已存在。字典在宏开始时应该是空的?我的命名范围循环并添加。然后 dict.exist 应该触发,如果值存在,它应该添加到我的 msg 字符串中,如果不存在,它应该添加到命名范围的底部。但是,该值现在添加到“A2”,而不是在范围的末尾,如果文本框中有不止一行,则覆盖自身。
Private Sub AddAnalyst()
' Select Tools->References from the Visual Basic menu.
' Check box beside "Microsoft Scripting Runtime" in the list.
Dim ws As Worksheet
Dim i As Long
Dim FreeRow As String
Dim TBLines() As String
Dim MsgAdd As String
Dim xFound As Integer
Dim Cell As Range
Dim Rng As Range
Dim dict As Object
Set Rng = Range("Name")
'Build Dictionary
Set dict = CreateObject("Scripting.Dictionary")
dict.CompareMode = vbTextCompare 'Capitalization does not apply
For Each Cell In Rng.Cells 'Loop through range & add to dictionary
dict.Item(Cell.Value) = Cell.Address(RowAbsolute:=False, ColumnAbsolute:=False)
Next Cell
TBLines = Split(Add_Analyst_Form.AddAnalystTB.Text, vbCrLf)
For i = LBound(TBLines) To UBound(TBLines)
If dict.Exists(i) Then 'Add to message string for end msgbox
xFound = xFound + 1
MsgAdd = MsgAdd & vbCrLf & UBound(TBLines, i)
Else
With ws
FreeRow = WorksheetFunction.CountA(Range("A:A")) + 1
Sheets("Lists").Range("A" & FreeRow) = TBLines(i)
End With
End If
Next i
If xFound <> 0 Then MsgBox ("Analyst(s)," & MsgAdd & ", is/are already entered into the database and will not be added.") 'msg name already exists
Set dict = Nothing
End Sub
以前尝试过(在字典之前):
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub AddAnalyst()
Dim ws As Worksheet
Dim i As Long
Dim FreeRow As String
Dim TBLines() As String
Dim MsgAdd As String
Dim sFind As String
Dim rFound As Range
Dim valueFound As Integer
TBLines = Split(Add_Analyst_Form.AddAnalystTB.Text, vbCrLf)
For i = LBound(TBLines) To UBound(TBLines) 'Cycle through all lines of the textbox
On Error Resume Next 'Skip error that will occur if rFound does not exist.
sFind = UBound(TBLines, i)
Set rFound = Sheets("Lists").Range("Name").Find(sFind, LookIn:=xlValues, LookAt:=xlWhole)
If Not rFound Is Nothing Then 'Add value to string for later MsgBox & increase integer
valueFound = valueFound + 1
MsgAdd = MsgAdd & vbCrLf & UBound(TBLines, i)
GoTo NextIteration
Else
With ws 'Name is not duplicated in range, add to range.
FreeRow = WorksheetFunction.CountA(Range("A:A")) + 1
Sheets("Lists").Range("A" & FreeRow) = TBLines(i)
End With
End If
NextIteration:
Next i
'Msgbox will be displayed if 1 or more of the values previously existed.
If valueFound <> 0 Then MsgBox ("Analyst(s)," & MsgAdd & ", is/are already entered into the database and will not be added.") 'msg name already exists
End Sub
我的脚本似乎没有检查重复项。它只是自动添加到我命名范围的底部。我认为这是由于我的 On Error Resume 但我似乎无法找到解决方法。如果有人有一些意见,将不胜感激。
【问题讨论】:
-
您好,我建议您使用 Dictionary 数据结构来跟踪您以前见过的项目,并且仅在它们是新的时才将它们添加到您的范围内。
-
我应该怎么做。据我了解,字典需要键和值。我只有一个我希望使用的命名范围。如何让字典填写随机值?
-
如果您愿意,可以将键和值设置为相同。
-
我是否必须遍历一个命名范围才能添加到字典中,或者我可以使用
RangeToDict Names("Name").RefersToRange, Names("Name").RefersToRange这样的东西吗?这给了我一个函数未定义的错误
标签: vba userform excel-2016