2016-06-26 143 views
0

Worksheet screenshot的Excel/VBA不知道从哪里开始

所以我做了一个简单的用户形式,将让人们能够轻松登出设备。我想这样做,如果“设备”栏中的内容出来了,它会在“输入/输出”栏中说出来。但如果设备显示“笔记本电脑1”和最后“日期&时间”列是空的,那么它将在“IN/OUT”列中的笔记本电脑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 
+0

欢迎来到Stack Overflow。 SO不是我网站或教学网站的代码,有许多网站可以帮助您理解基础知识。 SO是社区将帮助解决现有代码中特定问题的地方。如果您有现有的代码,请将其放在原始帖子中。 –

回答

3

1)A “形式” 是一个特定的在VBA编码构建体。根据你发布的内容,我假定你不是指它,而是只是将这张表格称为表格?如果没有,请发布您尝试过的VBA代码。 2)假设设备列表在“Tracker”列中,您应该使用该列表填充设备列中的下拉列表以确保它们匹配。我还假设您的额外设备列在下拉列表中没有任何内容,并且如果用户签出2个跟踪项目,则会为每个项目设置一个行条目。 (我建议摆脱那个专栏,如果你得到的用户误用它)

3)既然你问从哪里开始,我会给你。通过自己计算出确切的语法,您将学到更多东西。你可以谷歌“Excel VBA X”其中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 

随着你将要确保你有一个短回路测试,并通过一遍又一遍步骤你的循环untils。如果你的逻辑错误并且无限循环结束,你可以很容易地停止通过并修复它(或者在通过,然后停止和重新测试时修复它),但是如果你只是玩游戏,那么excel会冻结在你身上。

如果遇到特定步骤的问题,您可能会在SO上找到很多现有的东西。如果没有,请发布一个新的线程,其中包含该步骤的具体内容。这篇文章将会在几页之后下载,如果你把它放在这里,人们可能不会看到你的问题。此外,它应该拥有自己的线程,因为在那个时候您已经经过了“从哪里开始”的阶段。

祝你好运!