Excel VBA - 使文本框输入可选

Excel VBA - Make Textbox input optional

我的问题如下:

Userform visualization for understanding

(1) 我有一个 combobx "CGselectionStrategies",它应该是下面输入文本框的基础。当用户窗体启动时,我希望它显示这些框的先前输入,具体取决于组合框的选择。

输入保存在工作表"Commodity Groups"中,代码如下:

Private Sub SaveCGStrategies_Click()

'Just general stuff
Dim outputBook As Workbook
Set outputBook = ActiveWorkbook

'Note-fields for PU Strategies, incl. Authors
Dim CGselectionStrategies As String
Dim NoteTargetMarket As String
Dim AuthorTargetMarket As String
Dim NotePUMStrategy As String
Dim AuthorPUMStrategy As String
Dim NotePUSStrategy As String
Dim AuthorPUSStrategy As String
Dim NotePULStrategy As String
Dim AuthorPULStrategy As String

CGselectionStrategies = Me.CGselectionStrategies
NoteTargetMarket = Me.NoteTargetMarket
AuthorTargetMarket = Me.NoteAuthorMarketInfo
NotePUMStrategy = Me.NotePUMStrat
AuthorPUMStrategy = Me.NoteAuthorPUMStratInfo
NotePUSStrategy = Me.NotePUSStrat
AuthorPUSStrategy = Me.NoteAuthorPUSStratInfo
NotePULStrategy = Me.NotePULStrat
AuthorPULStrategy = Me.NoteAuthorPULStratInfo

'Save CG Strategies behind them in the List on CG Worksheet
outputBook.Activate
outputBook.Worksheets("Commodity Groups").Select

With Me.CGselectionStrategies
If Me.CGselectionStrategies.value = "Halbzeuge (und Rohstoffe)" Then
     Range("K2").Select
     ActiveCell.value = NoteTargetMarket
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = AuthorTargetMarket
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePUMStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPUMStratInfo
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePUSStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPUSStratInfo
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePULStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPULStratInfo
End If
If Me.CGselectionStrategies.value = "Mechanische Konstruktionsteile" Then
     Range("K62").Select
     ActiveCell.value = NoteTargetMarket
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = AuthorTargetMarket
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePUMStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPUMStratInfo
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePUSStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPUSStratInfo
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePULStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPULStratInfo
End If
If Me.CGselectionStrategies.value = "Norm- und Katalogteile (ausser Elektro)" Then
     Range("K87").Select
     ActiveCell.value = NoteTargetMarket
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = AuthorTargetMarket
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePUMStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPUMStratInfo
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePUSStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPUSStratInfo
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePULStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPULStratInfo
End If
If Me.CGselectionStrategies.value = "Elektrische, elektronische und optische Komponenten und Baugruppen" Then
     Range("K127").Select
     ActiveCell.value = NoteTargetMarket
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = AuthorTargetMarket
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePUMStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPUMStratInfo
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePUSStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPUSStratInfo
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePULStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPULStratInfo
End If
If Me.CGselectionStrategies.value = "Hilfs-, Betriebs- und Produktionshifsmittel" Then
     Range("K180").Select
     ActiveCell.value = NoteTargetMarket
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = AuthorTargetMarket
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePUMStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPUMStratInfo
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePUSStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPUSStratInfo
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePULStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPULStratInfo
End If
If Me.CGselectionStrategies.value = "Subsysteme und Anlagen" Then
     Range("K256").Select
     ActiveCell.value = NoteTargetMarket
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = AuthorTargetMarket
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePUMStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPUMStratInfo
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePUSStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPUSStratInfo
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePULStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPULStratInfo
End If
If Me.CGselectionStrategies.value = "Handelsware" Then
     Range("K299").Select
     ActiveCell.value = NoteTargetMarket
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = AuthorTargetMarket
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePUMStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPUMStratInfo
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePUSStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPUSStratInfo
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePULStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPULStratInfo
End If
If Me.CGselectionStrategies.value = "Dienstleistungen" Then
     Range("K310").Select
     ActiveCell.value = NoteTargetMarket
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = AuthorTargetMarket
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePUMStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPUMStratInfo
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePUSStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPUSStratInfo
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePULStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPULStratInfo
End If
If Me.CGselectionStrategies.value = "Allgemeines und Administration" Then
     Range("K360").Select
     ActiveCell.value = NoteTargetMarket
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = AuthorTargetMarket
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePUMStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPUMStratInfo
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePUSStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPUSStratInfo
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NotePULStrat
     ActiveCell.Offset(0, 1).Select
     ActiveCell.value = NoteAuthorPULStratInfo
End If
End With

End Sub

我的方法如下...

'Show old Strategies when selecting a combobox-item
'Start with short Text "Please choose a Commodity Group"
If Me.CGselectionStrategies.value = "" Then
   Me.NoteTargetMarket.Text = CStr(ThisWorkbook.Sheets("Commodity Groups").Range("K445").value)
   Me.Next Variable
   Me.Next Variable
   Me.Next Variable
End If
If Me.CGselectionStrategies.value = "Halbzeuge (und Rohstoffe)" Then
   Me.NoteTargetMarket.Text = CStr(ThisWorkbook.Sheets("Commodity Groups").Range("K2").value)
   Me.Next Variable
   Me.Next Variable
   Me.Next Variable
End If

...等等。不用说它不起作用。我在网上找到了以下内容,并尝试根据自己的能力对其进行改编,但没有成功。

'Change Textbot Content based on Combobox selection

Dim wks As Excel.Worksheet
Dim selectedString As Variant
Dim row As Long
Dim value As Variant

Set wks = Worksheets("Commodity Groups")

If CGselectionStrategies.ListIndex <> -1 Then
    selectedString = CGselectionStrategies.value

    On Error Resume Next
    row = Application.WorksheetFunction.Match(selectedString, wks.Columns(1), 0)
    On Error GoTo 0

    If row Then

        value = wks.Cells(row, 2)   
        DomainOwnerTestBox.value = value

    Else

        'Value not found in the worksheet 'test'

    End If

End If

End Sub

还有一个问题是有多个输入值,不仅在第 2 列中,它们还被许多其他行分隔。 我希望我的问题能以易于理解的方式得到解释。

(2) 我的第二个问题更短,是关于如何避免必须填写用户表单中的所有文本框。一个是问题有超过 200 个输入要填写,每当我想测试输入在数据库中的位置时,我都会遇到运行时 13 错误 "Type mismatch." 但是,如果我在每个框中都放一个输入,它顺利通过。这里有一段代码摘录了我如何从用户表单输入中保存数据:

Dim Datum As Date
Dim SName As String
Dim PotentialS As String
Dim SuppNr As Long
Dim Active As String

Datum = Me.TextBox117
SName = Me.SuppName
PotentialS = Me.PotentialS
SuppNr = Me.SuppNo
Active = Me.Active


'Go to the first empty line on the output sheet (Meta DB) in this workbook
outputBook.Activate
outputBook.Worksheets("Meta DB").Range("A3").Select


If outputBook.Worksheets("Meta DB").Range("A3").Offset(1, 0) <> "" Then
   outputBook.Worksheets("Meta DB").Range("A3").End(xlDown).Select
End If


'Go to A4 and from there always one below the last filled cell in A
ActiveCell.Offset(1, 0).Select
DatabaseRow = ActiveCell.row


'Post Values for new Entry
'Add a New Supplier Tab - Supplier Profile
ActiveCell.value = Datum
ActiveCell.Offset(0, 1).Select
ActiveCell.value = SName
ActiveCell.Offset(0, 1).Select
ActiveCell.value = PotentialS
ActiveCell.Offset(0, 1).Select
ActiveCell.value = SuppNr
ActiveCell.Offset(0, 1).Select

欢迎任何帮助和提示。

嗨,有一件事是肯定的 - 你需要摆脱所有这些 .Select

它们使阅读变得异常困难。我自己也才刚刚开始学习 VBA(大约 3 周前)。请看下面的 link - How to avoid using Select in Excel VBA macros 。它应该可以帮助您提高 VBA 的可读性。它还将使您的代码快上亿倍。

这也将帮助您不必使用 ActiveCell 每个其他命令。

另一个提示是代替你

Dim *StringVariable* as string

作为您从一开始就开始的一行代码 - 如果你想给一个单元格命名,只需给出它的范围,然后把它设为 "String" 例如

Range("A1") = "This is a String"

我对 VBA 没有足够的经验,不知道你的文本框有什么问题,但我希望这是一个好的开始,可以帮助你的一般 VBA 写作。

首先,我认为缩短 SaveCGStrategies_Click 代码将有助于更好地理解 VBA,您所做的是逐一检查每个选项以保存值,但考虑第一个选项是选择,那么您将永远不需要检查其他人,因为您会找到匹配项,代码每次也会重复,下面检查选择并运行一次代码的单个实例,但针对相关单元格。

Private Sub SaveCGStrategies_Click()
Dim LngRow      As Long
Dim outputBook  As Workbook
Dim outputSheet As Worksheet

Set outputBook = ActiveWorkbook
Set outputSheet = outputBook.Worksheets("Commodity Groups")

'With Me.CGselectionStrategies
Select Case Me.CGselectionStrategies.Value

    Case "Halbzeuge (und Rohstoffe)"
        LngRow = 2
    Case "Mechanische Konstruktionsteile"
        LngRow = 62

    Case "Norm- und Katalogteile (ausser Elektro)"
        LngRow = 87

    Case "Elektrische, elektronische und optische Komponenten und Baugruppen"
        LngRow = 127

    Case "Hilfs-, Betriebs- und Produktionshifsmittel"
        LngRow = 180

    Case "Subsysteme und Anlagen"
        LngRow = 256

    Case "Handelsware"
        LngRow = 299

    Case "Dienstleistungen"
        LngRow = 310

    Case "Allgemeines und Administration"
        LngRow = 360

End Select

outputSheet.Cells(LngRow, 11) = Me.NoteTargetMarket
outputSheet.Cells(LngRow, 13) = Me.NoteAuthorMarketInfo
outputSheet.Cells(LngRow, 14) = Me.NotePUMStrat
outputSheet.Cells(LngRow, 15) = Me.NoteAuthorPUMStratInfo
outputSheet.Cells(LngRow, 16) = Me.NotePUSStrat
outputSheet.Cells(LngRow, 17) = Me.NoteAuthorPUSStratInfo
outputSheet.Cells(LngRow, 18) = Me.NotePULStrat
outputSheet.Cells(LngRow, 19) = Me.NoteAuthorPULStratInfo

Set outputSheet = Nothing
Set outputBook = Nothing

End Sub

与您引用工作簿的方式相同,它也引用工作表,使我们能够用更少的代码写入我们想要的工作表范围。我没有使用您拥有的 .SelectActivate 函数,因为这些函数可能存在性能问题。我还直接引用了这些值,而不是先将它们放在变量中,如果您打算在将它们写入单元格之前对其进行操作,那么变量可能会有用,但如果它是从文本框到单元格的直接插入,我们可以直接通过。

你的第二个问题需要更多的输入才能确定,但​​我怀疑与数据类型有关。

Dim Datum As Date
Datum = Me.TextBox117

Me.TextBox117 日期格式是否有效?这可以如下检查:-

If IsDate(Me.TextBox117) then Datum = CDate(Me.TextBox117)

函数CDate确保将值作为日期传递给变量。

Dim SuppNr As Long
SuppNr = Me.SuppNo

Me.SuppNo 是一个有效的数字吗?这可以如下检查:-

If IsNumeric(Me.SuppNo) then SuppNr = CLng(Me.SuppNo)

我的建议是在让它工作时将它们全部设置为 String 或按原样传递它们。