Excel / VBA不知道从哪里开始

时间:2016-06-26 01:03:48

标签: vba excel-vba excel

Worksheet screenshot

所以我制作了一个简单的用户表单,允许人们轻松签出设备。我想这样做,如果“设备”栏中的某些内容出来了,它会在“输入/输出”栏中说出来。但另有说法。因此,如果设备说“笔记本电脑1”和最后“日期和时间”列是空的,那么它会在“输入/输出”列中的笔记本电脑1旁边说出来。设备列是多选的,设备选项之间带有“,”。

我不知道从哪里开始。到目前为止我所做的工作减去了填充用户表单条目的列表框和下拉列表。

Private Sub cmdout_Click()

Set ws = ThisWorkbook.Worksheets("SignOut")

Dim sh As Worksheet
Dim LastRow As Long

Dim i As Integer
For i = 0 To equip.ListCount - 1
If equip.Selected(i) Then
Msg = Msg & equip.List(i) & ", "
End If
Next i

Msg = Left(Msg, Len(Msg) - 2)

Dim rngFound As Range
Dim strFirst As String
Dim strID As String
Dim strDay As String
Dim taken As Integer

strID = gov.Value
strDay = ""

Set rngFound = Columns("C").Find(strID, Cells(Rows.Count, "C"), xlValues, xlWhole)
If Not rngFound Is Nothing Then
strFirst = rngFound.Address
Do
If LCase(Cells(rngFound.Row, "G").Text) = LCase(strDay) Then
MsgBox "GOV is still signed out."
taken = 1
End If
Set rngFound = Columns("C").Find(strID, rngFound, xlValues, xlWhole)
Loop While rngFound.Address <> strFirst
End If
If taken = 0 Then


Application.Worksheets("SignOut").Range("A" & Rows.Count).End(xlUp).Offset(1).Value = Now()
Application.Worksheets("SignOut").Range("B" & Rows.Count).End(xlUp).Offset(1).Value = techname.Value
Application.Worksheets("SignOut").Range("C" & Rows.Count).End(xlUp).Offset(1).Value = gov.Value
Application.Worksheets("SignOut").Range("D" & Rows.Count).End(xlUp).Offset(1).Value = Msg
Application.Worksheets("SignOut").Range("E" & Rows.Count).End(xlUp).Offset(1).Value = otherequip.Value




End If

Set rngFound = Nothing


End Sub

登录表单:

Private Sub CommandButton1_Click()

  Dim rngFound As Range
    Dim strFirst As String
    Dim strID As String
    Dim strDay As String

    strID = techname1.Value
    strDay = ""

    Set rngFound = Columns("B").Find(strID, Cells(Rows.Count, "B"), xlValues, xlWhole)
    If Not rngFound Is Nothing Then
        strFirst = rngFound.Address
        Do
            Application.Worksheets("SignOut").Cells(rngFound.Row, "G").Value = Now()
            Set rngFound = Columns("B").Find(strID, rngFound, xlValues, xlWhole)
        Loop While rngFound.Address <> strFirst
    End If

    Set rngFound = Nothing
End Sub

1 个答案:

答案 0 :(得分:3)

1)A&#34;形式&#34;是VBA中的特定编码构建体。根据您发布的内容,我假设您没有引用它,而只是将此表格称为表格?如果没有,请发布您尝试过的VBA代码。

2)假设设备列表在&#34; Tracker&#34;在列中,您应该使用该列表填充设备列中的下拉列表以确保它们匹配。我还假设您的额外设备列在下拉列表中没有任何内容,如果人们检查了2个跟踪项目,则每个项目都会有一个行条目。 (如果你的用户滥用它,我建议删除该列)

3)既然你问到哪里开始,我会给你那个。通过自己弄清楚确切的语法,您将学到更多东西。你可以google&#34; Excel VBA X&#34;其中X基本上都是这些行。

伪代码 - (不会运行,需要用实际代码替换 - 也忽略彩色单词,它们不代表伪代码中的任何内容)

Phase 1:
trigger event on save (event handler is another search term for trigger events)
Change all equipment values to In
loop through first date/time column
IF there is a value in that column and there is not a value in the second date/time column get the name of the equipment from the equipment column 
Find equipment from tracker column change In/Out value on that row to Out
continue the loop until the next row is blank

Alternate: 
remove code to check everything in
add on-edit trigger to equipment column 
add row that was edited to array
add on-edit trigger to check in date column
store row number to array
change loop so it only goes through rows in array
change if so that if something is checked out but not in, it is set out
(You will want to do this in case someone selects the wrong thing and then changes it - don't change it to out immediately or you will need logic to realize what was changed to out the previous time and change it back to in.)
else if something is checked out and has a value in check in date column then set it to in

Phase 2:
Implement an actual form that people use to fill in the sheet and check things in and out
Reuse relevant code from above but eliminate human error on dates and other things
(I suggest this as phase 2 as you can do this without a form and you will be using less new code. I would definitely use a form myself but it would be better if you wade into the pool instead of diving in. Unless you have coding experience and just need to learn syntax and vocab, then dive away.)

如果这是我正在制作的表格,我会做很多其他的事情,但这应该让你开始寻找建立这个项目的内容。我试图让它变得尽可能简单,这样它就不会让人不知所措。有更好的方法可以做到这一点,但这些方法应该是你可以快速掌握的方法,然后在你了解更多后再改进。祝你的设备跟踪好运!

代码发布后

编辑

好的,使用您发布的代码,一直到子行之前的顶部并输入:

Option Explicit

这将使VBE编辑器在很多情况下为您提供更有意义的反馈。例如,您在昏暗线之前有设定线。如果没有Option Explicit,当编辑器找到一个尚未使用Dim语句声明的变量时,它只是在运行时将其设置为变量类型。这会占用额外的内存,这意味着拼写错误会动态创建变量。所以,当你做你在这里所做的事情时,你最终会得到

Dim sh As Worksheet ' your sh variable is your worksheet variable. It never gets used again.
Set ws = ThisWorkbook.Worksheets("SignOut")' the ws here should likely be sh to match the Dim statement ... or the sh in the Dim should be a ws. Except it doesn't ever get used again either.

在这种情况下,这些都不重要,因为你没有重复使用它们,但是如果你的代码是指一个或另一个,你会希望编译器告诉你你正在尝试使用一个变量尚未宣布而不是创建一个新的。

通常,您希望将Dim语句全部放在子或函数的顶部。 1)更容易找到它们并调试或检查拼写。 2)它确保在脚本尝试引用它们之前声明它们。

此处的代码在引用变量之前不会填充变量。几乎任何时候你有一个变量,你需要填充它,然后才能用它做任何事情。有许多方法可以使用工作表中的数据填充变量。如果您对数组感到满意而不是后者(或集合而不是数组),那么您将可以更轻松地完成这样的任务。

一些特定的行:

Dim LastRow as Long 'you have this declared but you need to put in code to get the last row, which will be handy for populating variables later in your code. Do this right after declaring variables. Google excel vba find last row.
For i = 0 To equip.ListCount - 1 ' you need to populate equip before doing this. Lookup excel vba how to copy a range into variable. Then lookup how to loop through range. You can start it at your first line of data and go down to the LastRow to grab them all into the same array (which will basically be a table).
msg = Left(msg, Len(msg) - 2) 'lookup excel vba string manipulations if this isn't doing what you want
'these next lines all have <Variable Name>.value which won't work for you. If those variables are supposed to be things that the sheet prompts someone to enter and then they get populated here you can see how to do that here-> http://www.excel-vba-easy.com/vba-userform-excel-vba.html
Application.Worksheets("SignOut").Range("B" & Rows.Count).End(xlUp).Offset(1).Value = techname.Value
Application.Worksheets("SignOut").Range("C" & Rows.Count).End(xlUp).Offset(1).Value = gov.Value
Application.Worksheets("SignOut").Range("D" & Rows.Count).End(xlUp).Offset(1).Value = msg
Application.Worksheets("SignOut").Range("E" & Rows.Count).End(xlUp).Offset(1).Value = otherequip.Value

使用你的循环直到你需要确保你用一个短循环进行测试并一遍又一遍地执行它。如果你的逻辑错误并最终无限循环,你可以轻松地停止踩踏并修复它(或者在踩踏时修复它,然后停止并重新测试),但如果你只是点击播放,那么excel会冻结你。

如果您遇到特定步骤的问题,您可能会在SO上找到很多现有的东西。如果没有,请发布具有该步骤细节的新线程。到那时这个帖子将会缩短几页,如果你把它放在这里,人们很可能不会看到你的问题。此外,它将配得上自己的线程,因为你已经超越了&#34;从哪里开始&#34;那个阶段。

祝你好运!