Excel VBA - 用户表单中的单元格填充顺序 - 似乎几乎是随机的?
Excel VBA - Order of cell filling from a User Form - seems almost random?
也许这个 post 有点长,但我希望你能阅读它并为我提供一些意见。
我一直在努力为焊工资格考试记录 (WQTR) 制作用户表格。由于表单有 107 个字段,我创建了一个相当复杂的模块,允许用户保存他们的进度。与其输入冗长的解释,我在此处添加完整的模块。我在代码中做了详细的注释,但如果有什么需要解释的,请告诉我。
一切都编译得很好,除了一个例外,它做了我期望的事情。我假设(不确定为什么)文本框被脚本读取并输入工作表(全部在一行中)的顺序将与选项卡顺序同步。然而,事实并非如此。事实上,我看不出任何特定的顺序。我认为这与我如何根据用户表单中的标签为列创建 headers 有关,但我不确定。即使我将所有标签的 TabStop 属性设置为 False,我也确实确保了标签在 Tab 键顺序中的顺序正确。
下面是我在模块中的代码。我还有其他几个模块,但其中 none 应该与这个问题有关。
Option Explicit
Dim ws As Worksheet
Dim welderNameEntered As String
Dim welderName_ As Variant
Dim welderFirstName As String
Dim welderMiddlename As String
Dim welderLastName As String
Dim sheetName As String
Dim arrayLength As Integer
'********************************************************************************
'***Controls the order of execution in this module for all Subs and Functions.***
'********************************************************************************
Public Sub TempSaveProgress()
Application.ScreenUpdating = False
Call SplitName
funcCheckAndAddNewSheet sheetName
Call SaveData
Call Protection.DangerMouse(sheetName)
Application.ScreenUpdating = True
ActiveWorkbook.Save
End Sub
'************************************************************************************
'***Splits the Welders's first and last names by the space between them and grabs****
'***the first three characters of each. Sets the value of the sheetname variable***
'************************************************************************************
Sub SplitName()
welderNameEntered = WQTR_Form.welderNameText.Value
welderName_ = Split(welderNameEntered, " ")
Dim arrayLength As Integer
arrayLength = UBound(welderName_) - LBound(welderName_) + 1
Dim answer As Long
If arrayLength = 0 Then
Call ArrayLengthZero
Exit Sub
ElseIf arrayLength = 1 Then
Call ArrayLengthOneAndThree
Exit Sub
ElseIf arrayLength = 2 Then
welderFirstName = Left(welderName_(0), 3)
welderLastName = Left(welderName_(1), 3)
sheetName = "Temp-" + welderLastName + "-" + welderFirstName
ElseIf arrayLength = 3 Then
welderFirstName = Left(welderName_(0), 3)
welderMiddlename = Left(welderName_(1), 1)
welderLastName = Left(welderName_(2), 3)
sheetName = "Temp-" + welderLastName + "-" + welderFirstName + "-" + welderMiddlename
ElseIf arrayLength > 3 Then
Call ArrayLengthOneAndThree
Exit Sub
End If
End Sub
'**************************************************************************************
'***Adds and new worksheet after all other worksheets and gives it a temporary name.***
'**************************************************************************************
Function funcCheckAndAddNewSheet(argCheckAndAdd As String)
For Each ws In ThisWorkbook.Worksheets
If argCheckAndAdd = ws.Name Then
Call SheetNameAlreadyExists
End If
Next ws
If sheetName <> "" Then
Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = argCheckAndAdd
End If
End Function
'*****************************************
'***Message if the arrayLength is zero ***
'*****************************************
Sub ArrayLengthZero()
Dim answer As Long
answer = MsgBox("You must enter a welder's name in order to Save Your Progress.", vbOKOnly, "No name?")
End Sub
'**************************************************
'***Message if the arrayLength is One or Three. ***
'**************************************************
Sub ArrayLengthOneAndThree()
Dim answer As Long
answer = MsgBox("The Welder's Name you entered is not valid. The name must conform to one these examples:" + _
vbNewLine + vbNewLine + _
" 1. FirstName LastName as in John Doe." + vbNewLine + _
" 2. FirstName MiddleName LastName as in Franklin Deleno Roosevilt." + vbNewLine + _
" 3. FirstName MiddleInitial LastName as in Joe D. Public." + vbNewLine + vbNewLine + _
"You also must make sure that names are no more than three names. " + _
"A name such as Roy Wayne David Johnson will not work. " + _
"In such cases, one of the two middle names must be omitted." _
, vbOKOnly, "Name is incorrect")
End Sub
'******************************************************************************
'***Message if sheetName matches the name of an already existing worksheet. ***
'******************************************************************************
Sub SheetNameAlreadyExists()
Dim answer As Long
answer = MsgBox("A WorkSheet by by the name " + sheetName + " already exists." + _
" Did you already Save Progress for this welder on another occasion?" + _
" If so, would you like to overwrite the data in the Worksheet named " + _
sheetName + "?", vbYesNo, sheetName + " Already Exists.")
If answer = vbYes Then
Call SafeMouse
Worksheets(sheetName).Activate
Application.DisplayAlerts = False
Worksheets(sheetName).Delete
Application.DisplayAlerts = True
Exit Sub
Else
Exit Sub
End If
End Sub
'****************************************************************************************
'***Sets the Active Sheet for all of the subs it calls. Again, this basically ***
'***controls the order of execution. Then does some minor worksheet level formatting. ***
'****************************************************************************************
Private Sub SaveData()
Worksheets(sheetName).Activate
Call LabelNames
Call LabelCaptions
Call TextBoxText
Call DeleteEmptyColumns
'-----Worksheet-level Formatting-----
Worksheets(sheetName).range("A1:DD1").Font.Bold = True
Worksheets(sheetName).Columns("A:DD").AutoFit
End Sub
'***************************************************************************************
'***Takes the names of all of the form lables and enters them in the first row of the***
'***active sheet. ***
'***************************************************************************************
Private Sub LabelNames()
Dim ctlLblName As control
Dim col As Integer: col = 0
For Each ctlLblName In WQTR_Form.Controls
If TypeName(ctlLblName) = "Label" Then
col = col + 1
Cells(1, col).Value = ctlLblName.Name
Cells(1, col).Interior.ColorIndex = 15
End If
Next ctlLblName
End Sub
'*******************************************************************************************
'***Takes the captions of all of the form lables and enters them in the second row of the***
'***active sheet. ***
'*******************************************************************************************
Private Sub LabelCaptions()
Dim ctlLblCaption As control
Dim col As Integer: col = 0
For Each ctlLblCaption In WQTR_Form.Controls
If TypeName(ctlLblCaption) = "Label" Then
col = col + 1
Cells(2, col).Value = ctlLblCaption.Caption
Cells(2, col).Interior.ColorIndex = 6
End If
Next ctlLblCaption
End Sub
'***************************************************************************************************
'***The Label Names and the TextBox Names were made to be identical except for the last part of ***
'***the names which are "Label" and "Text", respectively. This code finds all TextBox Names, ***
'***strips "Text" out of the TexBox Name and replaces it with "Label" which makes it identical ***
'***to the Label Name. Then it searches for the label name in the active sheet. When a match ***
'***found it inserts the TextBox.Text Value (entered by the user) in the cell in row three. ***
'***************************************************************************************************
Private Sub TextBoxText()
Dim ctlTxtBx As control
Dim col As Variant: col = 0
Dim strTextBoxName As String
Dim strShortenedTxtBxName As String
Dim strConvertedTxtBxName As String
For Each ctlTxtBx In WQTR_Form.Controls
If TypeName(ctlTxtBx) = "TextBox" Then
strTextBoxName = ctlTxtBx.Name
strShortenedTxtBxName = Left(strTextBoxName, Len(strTextBoxName) - 4)
strConvertedTxtBxName = strShortenedTxtBxName + "Label"
col = Application.Match(strConvertedTxtBxName, Worksheets(sheetName).Rows(1), 0)
col = CInt(col)
Cells(3, col).Value = ctlTxtBx.Text
End If
Next ctlTxtBx
End Sub
'******************************************************************************************************
'***Search columns from A through DF (110) and deletes columns where the cell in row three is empty.***
'******************************************************************************************************
Private Sub DeleteEmptyColumns()
Dim col As Integer
For col = 110 To 1 Step -1
If Cells(3, col) = "" Then
ActiveSheet.Columns(col).Delete
End If
Next col
End Sub
所以,根据 Tab 键顺序,我所期望的结果如下
'| welderNameLabel | testDateLabel | wqtrNumberLabel | shopLabel | companyNameLabel | revisionNumberLabel | wpsNumberLabel | bm1_specificationLabel |
'|---------------- | ------------- | --------------- | --------- | ---------------- | ------------------- | -------------- | ---------------------- |
'| Welder Name | Test Date | WQTR Number | Shop | Company Name | Revision Number | WPS Number | Specification |
'|---------------- | ------------- | --------------- | --------- | ---------------- | ------------------- | -------------- | ---------------------- |
'| Dean Marin | 5-23-2017 | DM-1234-6G-FCAW | Bravo | ABC Company | Rev. 0 | 12345 | AWS D1.1 Code |
我实际得到的是这样的:
'| testDateLabel | welderNameLabel | companyNameLabel | shopLabel | wqtrNumberLabel | revisionNumberLabel | wpsNumberLabel | bm1_specificationLabel |
'| ------------- | --------------- | ---------------- | --------- | --------------- | ------------------- | -------------- | ---------------------- |
'| Test Date | Welder Name | Company Name | Shop | WQTR Number | Revision Number | WPS Number | Specification |
'| ------------- | --------------- | ---------------- | --------- | --------------- | ------------------- | -------------- | ---------------------- |
'| 5-23-2017 | Dean Marin | ABC Company | Bravo | DM-1234-6G-FCAW | Rev. 0 | 12345 | AWS D1.1 Code |
我已经对此进行了多次测试,它总是以完全相同的顺序将数据放入工作表中。我可以编写一些代码来按我想要的顺序对它进行排序,但在我这样做之前,我想 post 这个问题,看看是否有人对它为什么这样运行有任何想法。我有点担心我会写一些东西来对列进行排序,然后发现我的实验具有误导性,并且数据条目的顺序确实比看起来的 运行dom 多。
我的代码只是为用户窗体中的每个文本框编写了一行代码,并明确指定了数据应该放在的确切单元格,但我想要一些更通用的东西,我可以在我计划的其他工作簿中进行调整,因为它们彼此相关 -(焊接程序、程序资格和焊工资格连续性日志)。
也许有人知道一些方法可以在输入数据之前控制这个顺序,而不是在输入数据之后进行某种排序操作?
感谢任何回复。
更新和回答
我同意 jsotola 的观点,它们必须按照它们创建的顺序进行排序。 jsotola 提供了一些代码来列出顺序,我 运行 它多次并且总是以完全相同的顺序得到完全相同的列表。
谜底揭晓!
如果你有兴趣,这里是列表。我非常同意答案的部分原因是,根据记忆,我可以说这是我将控件添加到窗体的顺序。如果您浏览控件,您将看到名称的逻辑分组。当您阅读列表时,它们是相互关联的。
bm1_tubeSizeText
bm1_pipeFrame
bm1_pipeDiameterLabel
bm1_pipeDiameterText
baseMetalFrame2
bm2_baseMetalListBox
bm2_specificationLabel
bm2_specificationText
bm2_awsGroupNumberText
bm2_awsGroupNumberLabel
bm2_gradeLabel
bm2_gradeText
bm2_plateFrame
bm2_plateThicknessLabel
bm2_plateThicknessText
bm2_tubeFrame
bm2_tubeWallThicknessLabel
bm2_tubeWallThicknessText
bm2_tubeSizeLabel
bm2_tubeSizeText
bm2_pipeFrame
bm2_pipeSizeLabel
bm2_pipeSizeText
bm2_pipeSheduleLabel
bm2_pipeSheduleText
bm2_pipeDiameterLabel
bm2_pipeDiameterText
actualTestValuesFrame
atv_TypeOfWeldJointText
atv_filletPipeDiameterText
atv_filletPipeDiameterLabel
atv_baseMetalLabel
atv_baseMetalText
atv_filletFrame
atv_filletPipeTubeThicknessLabel
atv_filletPipeTubeThicknessText
atv_filletPlateThicknessLabel
atv_filletPlateThicknessText
atv_weldingFrame
atv_processLabel
atv_processText
atv_TypeOfWeldJointLabel
atv_grooveFrame
atv_groovePipeTubeThicknessLabel
atv_groovePipeTubeThicknessText
atv_groovePlateThicknessLabel
atv_groovePlateThicknessText
atv_groovePipeDiameterLabel
atv_groovePipeDiameterText
atv_processTypeLabel
atv_processTypeText
atv_backingLabel
atv_backingText
atv_weldingProcessFrame
atv_InstructionLabel_1
atv_InstructionLabel_2
atv_fillerMetalFrame
atv_awsSpecLabel
atv_awsSpecText
atv_awsClassificationLabel
atv_awsClassificationText
atv_fNumberLabel
atv_fNumberText
atv_positionFrame
atv_positionWeldedLabel
atv_positionWeldedText
rq_transferModeLabel
rq_transferModeText
rq_progressionLabel
rq_progressionText
atv_InstructionLabel_3
rq_InstructionLabel_4
rq_InstructionLabel_5
rq_singleOrMultipleElectrodesLabel
rq_singleOrMultipleElectrodesText
rq_gasFluxTypeLabel
rq_gasFluxTypeText
rangesQualiifedFrame
rq_weldingFrame
rq_weldingProcessFrame
rq_processLabel
rq_processText
rq_processTypeLabel
rq_processTypeText
rq_backingLabel
rq_backingText
rq_InstructionLabel_1
rq_InstructionLabel_2
rq_fillerMetalFrame
rq_awsSpecLabel
rq_awsSpecText
rq_awsClassificationLabel
rq_awsClassificationText
rq_fNumberLabel
rq_fNumberText
rq_positionFrame
rq_groovePipe24DownLabel
rq_groovePipe24DownText
rq_groovePlatePipe24UpLabel
rq_groovePlatePipe24UpText
rq_filletPlatePipe24UpLabel
rq_filletPlatePipe24UpText
rq_filletPipe24DownLabel
rq_filletPipe24DownText
rq_TypeOfWeldJointLabel
rq_TypeOfWeldJointText
rq_baseMetalLabel
rq_baseMetalText
rq_filletFrame
rq_filletPipeTubeThicknessLabel
rq_filletPipeTubeThicknessText
rq_filletPlateThicknessLabel
rq_filletPlateThicknessText
rq_filletPipeDiameterLabel
rq_filletPipeDiameterText
rq_grooveFrame
rq_groovePipeTubeThicknessLabel
rq_groovePipeTubeThicknessText
rq_groovePlateThicknessLabel
rq_groovePlateThicknessText
rq_groovePipeDiameterLabel
rq_groovePipeDiameterText
atv_gasFluxTypeText
atv_transferModeLabel
atv_transferModeText
atv_progressionLabel
atv_progressionText
atv_InstructionLabel_4
atv_InstructionLabel_5
atv_singleOrMultipleElectrodesLabel
atv_singleOrMultipleElectrodesText
atv_gasFluxTypeLabel
testResultsFrame
acceptanceCriteria_1Label
acceptanceCriteria_1Text
typeOfTest_1Label
typeOfTest_1Text
results_1Label
results_1Text
remarks_1Label
remarks_1Text
acceptanceCriteria_3Text
typeOfTest_3Text
results_3Text
remarks_3Text
acceptanceCriteria_2Text
typeOfTest_2Text
results_2Text
remarks_2Text
acceptanceCriteria_4Text
typeOfTest_4Text
results_4Text
remarks_4Text
acceptanceCriteria_5Text
typeOfTest_5Text
results_5Text
remarks_5Text
certificationFrame
laboratoryLabel
laboratoryText
testConductedByLabel
testNumberLabel
testNumberText
fileNumberLabel
fileNumberText
certStatementLabel_1
codeYearText
certStatementLabel_2
certStatementLabel_3
manufacturerOrContractorLabel
manufacturerOrContractorText
authorizedByLabel
authorizedByText
dateLabel
dateText
finishFrame
finishInstructionsLabel
saveProgressButton
rq_positionsQualifiedFrame
testConductedByText
AbortButton
typeOfTest_2Label
acceptanceCriteria_2Label
results_2Label
remarks_2Label
typeOfTest_3Label
typeOfTest_4Label
typeOfTest_5Label
acceptanceCriteria_3Label
acceptanceCriteria_4Label
acceptanceCriteria_5Label
results_3Label
results_4Label
results_5Label
remarks_3Label
remarks_4Label
remarks_5Label
WelderIDLabel
WelderIDText
这将显示表单控件的创建顺序
Private Sub UserForm_Click() ' runs when form background is clicked
Stop ' put here so that the code window shows up ( press F8 or F5 to continue)
Dim i As Integer
For i = 0 To UserForm1.Controls.Count - 1
Debug.Print UserForm1.Controls(i).Name
Next i
stop
End Sub
也许这个 post 有点长,但我希望你能阅读它并为我提供一些意见。
我一直在努力为焊工资格考试记录 (WQTR) 制作用户表格。由于表单有 107 个字段,我创建了一个相当复杂的模块,允许用户保存他们的进度。与其输入冗长的解释,我在此处添加完整的模块。我在代码中做了详细的注释,但如果有什么需要解释的,请告诉我。
一切都编译得很好,除了一个例外,它做了我期望的事情。我假设(不确定为什么)文本框被脚本读取并输入工作表(全部在一行中)的顺序将与选项卡顺序同步。然而,事实并非如此。事实上,我看不出任何特定的顺序。我认为这与我如何根据用户表单中的标签为列创建 headers 有关,但我不确定。即使我将所有标签的 TabStop 属性设置为 False,我也确实确保了标签在 Tab 键顺序中的顺序正确。
下面是我在模块中的代码。我还有其他几个模块,但其中 none 应该与这个问题有关。
Option Explicit
Dim ws As Worksheet
Dim welderNameEntered As String
Dim welderName_ As Variant
Dim welderFirstName As String
Dim welderMiddlename As String
Dim welderLastName As String
Dim sheetName As String
Dim arrayLength As Integer
'********************************************************************************
'***Controls the order of execution in this module for all Subs and Functions.***
'********************************************************************************
Public Sub TempSaveProgress()
Application.ScreenUpdating = False
Call SplitName
funcCheckAndAddNewSheet sheetName
Call SaveData
Call Protection.DangerMouse(sheetName)
Application.ScreenUpdating = True
ActiveWorkbook.Save
End Sub
'************************************************************************************
'***Splits the Welders's first and last names by the space between them and grabs****
'***the first three characters of each. Sets the value of the sheetname variable***
'************************************************************************************
Sub SplitName()
welderNameEntered = WQTR_Form.welderNameText.Value
welderName_ = Split(welderNameEntered, " ")
Dim arrayLength As Integer
arrayLength = UBound(welderName_) - LBound(welderName_) + 1
Dim answer As Long
If arrayLength = 0 Then
Call ArrayLengthZero
Exit Sub
ElseIf arrayLength = 1 Then
Call ArrayLengthOneAndThree
Exit Sub
ElseIf arrayLength = 2 Then
welderFirstName = Left(welderName_(0), 3)
welderLastName = Left(welderName_(1), 3)
sheetName = "Temp-" + welderLastName + "-" + welderFirstName
ElseIf arrayLength = 3 Then
welderFirstName = Left(welderName_(0), 3)
welderMiddlename = Left(welderName_(1), 1)
welderLastName = Left(welderName_(2), 3)
sheetName = "Temp-" + welderLastName + "-" + welderFirstName + "-" + welderMiddlename
ElseIf arrayLength > 3 Then
Call ArrayLengthOneAndThree
Exit Sub
End If
End Sub
'**************************************************************************************
'***Adds and new worksheet after all other worksheets and gives it a temporary name.***
'**************************************************************************************
Function funcCheckAndAddNewSheet(argCheckAndAdd As String)
For Each ws In ThisWorkbook.Worksheets
If argCheckAndAdd = ws.Name Then
Call SheetNameAlreadyExists
End If
Next ws
If sheetName <> "" Then
Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = argCheckAndAdd
End If
End Function
'*****************************************
'***Message if the arrayLength is zero ***
'*****************************************
Sub ArrayLengthZero()
Dim answer As Long
answer = MsgBox("You must enter a welder's name in order to Save Your Progress.", vbOKOnly, "No name?")
End Sub
'**************************************************
'***Message if the arrayLength is One or Three. ***
'**************************************************
Sub ArrayLengthOneAndThree()
Dim answer As Long
answer = MsgBox("The Welder's Name you entered is not valid. The name must conform to one these examples:" + _
vbNewLine + vbNewLine + _
" 1. FirstName LastName as in John Doe." + vbNewLine + _
" 2. FirstName MiddleName LastName as in Franklin Deleno Roosevilt." + vbNewLine + _
" 3. FirstName MiddleInitial LastName as in Joe D. Public." + vbNewLine + vbNewLine + _
"You also must make sure that names are no more than three names. " + _
"A name such as Roy Wayne David Johnson will not work. " + _
"In such cases, one of the two middle names must be omitted." _
, vbOKOnly, "Name is incorrect")
End Sub
'******************************************************************************
'***Message if sheetName matches the name of an already existing worksheet. ***
'******************************************************************************
Sub SheetNameAlreadyExists()
Dim answer As Long
answer = MsgBox("A WorkSheet by by the name " + sheetName + " already exists." + _
" Did you already Save Progress for this welder on another occasion?" + _
" If so, would you like to overwrite the data in the Worksheet named " + _
sheetName + "?", vbYesNo, sheetName + " Already Exists.")
If answer = vbYes Then
Call SafeMouse
Worksheets(sheetName).Activate
Application.DisplayAlerts = False
Worksheets(sheetName).Delete
Application.DisplayAlerts = True
Exit Sub
Else
Exit Sub
End If
End Sub
'****************************************************************************************
'***Sets the Active Sheet for all of the subs it calls. Again, this basically ***
'***controls the order of execution. Then does some minor worksheet level formatting. ***
'****************************************************************************************
Private Sub SaveData()
Worksheets(sheetName).Activate
Call LabelNames
Call LabelCaptions
Call TextBoxText
Call DeleteEmptyColumns
'-----Worksheet-level Formatting-----
Worksheets(sheetName).range("A1:DD1").Font.Bold = True
Worksheets(sheetName).Columns("A:DD").AutoFit
End Sub
'***************************************************************************************
'***Takes the names of all of the form lables and enters them in the first row of the***
'***active sheet. ***
'***************************************************************************************
Private Sub LabelNames()
Dim ctlLblName As control
Dim col As Integer: col = 0
For Each ctlLblName In WQTR_Form.Controls
If TypeName(ctlLblName) = "Label" Then
col = col + 1
Cells(1, col).Value = ctlLblName.Name
Cells(1, col).Interior.ColorIndex = 15
End If
Next ctlLblName
End Sub
'*******************************************************************************************
'***Takes the captions of all of the form lables and enters them in the second row of the***
'***active sheet. ***
'*******************************************************************************************
Private Sub LabelCaptions()
Dim ctlLblCaption As control
Dim col As Integer: col = 0
For Each ctlLblCaption In WQTR_Form.Controls
If TypeName(ctlLblCaption) = "Label" Then
col = col + 1
Cells(2, col).Value = ctlLblCaption.Caption
Cells(2, col).Interior.ColorIndex = 6
End If
Next ctlLblCaption
End Sub
'***************************************************************************************************
'***The Label Names and the TextBox Names were made to be identical except for the last part of ***
'***the names which are "Label" and "Text", respectively. This code finds all TextBox Names, ***
'***strips "Text" out of the TexBox Name and replaces it with "Label" which makes it identical ***
'***to the Label Name. Then it searches for the label name in the active sheet. When a match ***
'***found it inserts the TextBox.Text Value (entered by the user) in the cell in row three. ***
'***************************************************************************************************
Private Sub TextBoxText()
Dim ctlTxtBx As control
Dim col As Variant: col = 0
Dim strTextBoxName As String
Dim strShortenedTxtBxName As String
Dim strConvertedTxtBxName As String
For Each ctlTxtBx In WQTR_Form.Controls
If TypeName(ctlTxtBx) = "TextBox" Then
strTextBoxName = ctlTxtBx.Name
strShortenedTxtBxName = Left(strTextBoxName, Len(strTextBoxName) - 4)
strConvertedTxtBxName = strShortenedTxtBxName + "Label"
col = Application.Match(strConvertedTxtBxName, Worksheets(sheetName).Rows(1), 0)
col = CInt(col)
Cells(3, col).Value = ctlTxtBx.Text
End If
Next ctlTxtBx
End Sub
'******************************************************************************************************
'***Search columns from A through DF (110) and deletes columns where the cell in row three is empty.***
'******************************************************************************************************
Private Sub DeleteEmptyColumns()
Dim col As Integer
For col = 110 To 1 Step -1
If Cells(3, col) = "" Then
ActiveSheet.Columns(col).Delete
End If
Next col
End Sub
所以,根据 Tab 键顺序,我所期望的结果如下
'| welderNameLabel | testDateLabel | wqtrNumberLabel | shopLabel | companyNameLabel | revisionNumberLabel | wpsNumberLabel | bm1_specificationLabel |
'|---------------- | ------------- | --------------- | --------- | ---------------- | ------------------- | -------------- | ---------------------- |
'| Welder Name | Test Date | WQTR Number | Shop | Company Name | Revision Number | WPS Number | Specification |
'|---------------- | ------------- | --------------- | --------- | ---------------- | ------------------- | -------------- | ---------------------- |
'| Dean Marin | 5-23-2017 | DM-1234-6G-FCAW | Bravo | ABC Company | Rev. 0 | 12345 | AWS D1.1 Code |
我实际得到的是这样的:
'| testDateLabel | welderNameLabel | companyNameLabel | shopLabel | wqtrNumberLabel | revisionNumberLabel | wpsNumberLabel | bm1_specificationLabel |
'| ------------- | --------------- | ---------------- | --------- | --------------- | ------------------- | -------------- | ---------------------- |
'| Test Date | Welder Name | Company Name | Shop | WQTR Number | Revision Number | WPS Number | Specification |
'| ------------- | --------------- | ---------------- | --------- | --------------- | ------------------- | -------------- | ---------------------- |
'| 5-23-2017 | Dean Marin | ABC Company | Bravo | DM-1234-6G-FCAW | Rev. 0 | 12345 | AWS D1.1 Code |
我已经对此进行了多次测试,它总是以完全相同的顺序将数据放入工作表中。我可以编写一些代码来按我想要的顺序对它进行排序,但在我这样做之前,我想 post 这个问题,看看是否有人对它为什么这样运行有任何想法。我有点担心我会写一些东西来对列进行排序,然后发现我的实验具有误导性,并且数据条目的顺序确实比看起来的 运行dom 多。
我的代码只是为用户窗体中的每个文本框编写了一行代码,并明确指定了数据应该放在的确切单元格,但我想要一些更通用的东西,我可以在我计划的其他工作簿中进行调整,因为它们彼此相关 -(焊接程序、程序资格和焊工资格连续性日志)。
也许有人知道一些方法可以在输入数据之前控制这个顺序,而不是在输入数据之后进行某种排序操作?
感谢任何回复。
更新和回答
我同意 jsotola 的观点,它们必须按照它们创建的顺序进行排序。 jsotola 提供了一些代码来列出顺序,我 运行 它多次并且总是以完全相同的顺序得到完全相同的列表。
谜底揭晓!
如果你有兴趣,这里是列表。我非常同意答案的部分原因是,根据记忆,我可以说这是我将控件添加到窗体的顺序。如果您浏览控件,您将看到名称的逻辑分组。当您阅读列表时,它们是相互关联的。
bm1_tubeSizeText
bm1_pipeFrame
bm1_pipeDiameterLabel
bm1_pipeDiameterText
baseMetalFrame2
bm2_baseMetalListBox
bm2_specificationLabel
bm2_specificationText
bm2_awsGroupNumberText
bm2_awsGroupNumberLabel
bm2_gradeLabel
bm2_gradeText
bm2_plateFrame
bm2_plateThicknessLabel
bm2_plateThicknessText
bm2_tubeFrame
bm2_tubeWallThicknessLabel
bm2_tubeWallThicknessText
bm2_tubeSizeLabel
bm2_tubeSizeText
bm2_pipeFrame
bm2_pipeSizeLabel
bm2_pipeSizeText
bm2_pipeSheduleLabel
bm2_pipeSheduleText
bm2_pipeDiameterLabel
bm2_pipeDiameterText
actualTestValuesFrame
atv_TypeOfWeldJointText
atv_filletPipeDiameterText
atv_filletPipeDiameterLabel
atv_baseMetalLabel
atv_baseMetalText
atv_filletFrame
atv_filletPipeTubeThicknessLabel
atv_filletPipeTubeThicknessText
atv_filletPlateThicknessLabel
atv_filletPlateThicknessText
atv_weldingFrame
atv_processLabel
atv_processText
atv_TypeOfWeldJointLabel
atv_grooveFrame
atv_groovePipeTubeThicknessLabel
atv_groovePipeTubeThicknessText
atv_groovePlateThicknessLabel
atv_groovePlateThicknessText
atv_groovePipeDiameterLabel
atv_groovePipeDiameterText
atv_processTypeLabel
atv_processTypeText
atv_backingLabel
atv_backingText
atv_weldingProcessFrame
atv_InstructionLabel_1
atv_InstructionLabel_2
atv_fillerMetalFrame
atv_awsSpecLabel
atv_awsSpecText
atv_awsClassificationLabel
atv_awsClassificationText
atv_fNumberLabel
atv_fNumberText
atv_positionFrame
atv_positionWeldedLabel
atv_positionWeldedText
rq_transferModeLabel
rq_transferModeText
rq_progressionLabel
rq_progressionText
atv_InstructionLabel_3
rq_InstructionLabel_4
rq_InstructionLabel_5
rq_singleOrMultipleElectrodesLabel
rq_singleOrMultipleElectrodesText
rq_gasFluxTypeLabel
rq_gasFluxTypeText
rangesQualiifedFrame
rq_weldingFrame
rq_weldingProcessFrame
rq_processLabel
rq_processText
rq_processTypeLabel
rq_processTypeText
rq_backingLabel
rq_backingText
rq_InstructionLabel_1
rq_InstructionLabel_2
rq_fillerMetalFrame
rq_awsSpecLabel
rq_awsSpecText
rq_awsClassificationLabel
rq_awsClassificationText
rq_fNumberLabel
rq_fNumberText
rq_positionFrame
rq_groovePipe24DownLabel
rq_groovePipe24DownText
rq_groovePlatePipe24UpLabel
rq_groovePlatePipe24UpText
rq_filletPlatePipe24UpLabel
rq_filletPlatePipe24UpText
rq_filletPipe24DownLabel
rq_filletPipe24DownText
rq_TypeOfWeldJointLabel
rq_TypeOfWeldJointText
rq_baseMetalLabel
rq_baseMetalText
rq_filletFrame
rq_filletPipeTubeThicknessLabel
rq_filletPipeTubeThicknessText
rq_filletPlateThicknessLabel
rq_filletPlateThicknessText
rq_filletPipeDiameterLabel
rq_filletPipeDiameterText
rq_grooveFrame
rq_groovePipeTubeThicknessLabel
rq_groovePipeTubeThicknessText
rq_groovePlateThicknessLabel
rq_groovePlateThicknessText
rq_groovePipeDiameterLabel
rq_groovePipeDiameterText
atv_gasFluxTypeText
atv_transferModeLabel
atv_transferModeText
atv_progressionLabel
atv_progressionText
atv_InstructionLabel_4
atv_InstructionLabel_5
atv_singleOrMultipleElectrodesLabel
atv_singleOrMultipleElectrodesText
atv_gasFluxTypeLabel
testResultsFrame
acceptanceCriteria_1Label
acceptanceCriteria_1Text
typeOfTest_1Label
typeOfTest_1Text
results_1Label
results_1Text
remarks_1Label
remarks_1Text
acceptanceCriteria_3Text
typeOfTest_3Text
results_3Text
remarks_3Text
acceptanceCriteria_2Text
typeOfTest_2Text
results_2Text
remarks_2Text
acceptanceCriteria_4Text
typeOfTest_4Text
results_4Text
remarks_4Text
acceptanceCriteria_5Text
typeOfTest_5Text
results_5Text
remarks_5Text
certificationFrame
laboratoryLabel
laboratoryText
testConductedByLabel
testNumberLabel
testNumberText
fileNumberLabel
fileNumberText
certStatementLabel_1
codeYearText
certStatementLabel_2
certStatementLabel_3
manufacturerOrContractorLabel
manufacturerOrContractorText
authorizedByLabel
authorizedByText
dateLabel
dateText
finishFrame
finishInstructionsLabel
saveProgressButton
rq_positionsQualifiedFrame
testConductedByText
AbortButton
typeOfTest_2Label
acceptanceCriteria_2Label
results_2Label
remarks_2Label
typeOfTest_3Label
typeOfTest_4Label
typeOfTest_5Label
acceptanceCriteria_3Label
acceptanceCriteria_4Label
acceptanceCriteria_5Label
results_3Label
results_4Label
results_5Label
remarks_3Label
remarks_4Label
remarks_5Label
WelderIDLabel
WelderIDText
这将显示表单控件的创建顺序
Private Sub UserForm_Click() ' runs when form background is clicked
Stop ' put here so that the code window shows up ( press F8 or F5 to continue)
Dim i As Integer
For i = 0 To UserForm1.Controls.Count - 1
Debug.Print UserForm1.Controls(i).Name
Next i
stop
End Sub