我有一个数据库表,它存储有关各种项目的信息。它看起来像这样:
Project ID | Field | Truth Value
dog | 1a | True
dog | 1b | True
dog | 1c | False
cat | 1a | True
cat | 1b | True
cat | 1c | False
我想做的是能够循环完成这些项目。我有两个我不确定非常有效的想法。第一个想法是使用如下过滤器:
Columns("B:B").AutoFilter
Range("B:B").AutoFilter Field:=1, Criteria1:="1a", Operator:=xlFilterValues
然后使用剩余的值,或者其次使用每个项目有3个字段的事实,只需在用于获取项目名称的行号中添加3即可。
实际上,项目更复杂,因为真值对应于另一页上的勾选框,因此了解是否有更简单的方法来完成所有这些操作对我来说非常重要。<将这个放到上下文中的想法是,在所述其他页面上,可以在项目之间轻弹,同时查看/编辑为每个项目打勾的框。
答案 0 :(得分:1)
这是另一个可能的答案,它涉及更多,但非常快。您可以使用ADODB查询Excel工作表,就好像它是一个数据库一样。如果你想为每个不同的项目获得“真实”的真值,或者一些类似的数据存储性,这将是很方便的。 (这是一个词,dangit)。
Sub LoopDistinctProjects()
'Variables
Dim objConn As Object
Dim rs As Object
Dim strFileName As String, strSQL As String, strConn As String
Dim wsTable As Worksheet
'Sheet with the data
Set wsTable = ThisWorkbook.Sheets("Sheet1")
'Make a new file with _tmp appended to it in same folder
strFileName = ThisWorkbook.Path & "/" & ThisWorkbook.Name
strFileName = Replace(strFileName, ".xls", "_tmp.xls")
ThisWorkbook.SaveCopyAs strFileName
'Fancy ADODB stuff.. essentially open up that copy we just saves as if it were a database
Set objConn = CreateObject("ADODB.Connection")
strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strFileName & ";Extended Properties=""Excel 12.0 Xml;HDR=YES;"""
objConn.Open strConn
'This is the sql string we will use to query the excel/database. The field names are the names in Row 1 of the sheet
strSQL = "SELECT [Project] FROM [" & wsTable.Name & "$] WHERE [Project] IS NOT NULL GROUP BY [Project];"
'Fancy ADODB stuff to apply that SQL statement to the excel/database
Set rs = CreateObject("ADODB.Recordset")
rs.Open strSQL, objConn
'move to the first record (it's already there... probably)
rs.Movefirst
Do While Not rs.EOF
Debug.Print rs.Fields("Project").Value '<----That's a distinct project right there.
rs.movenext
Loop
'close it up
rs.Close
objConn.Close
'Remove that tmp workbook
Kill strFileName
End Sub
高级别,这会将工作表的副本放在同一文件夹中,然后使用ADODB使用ACE OLEDB提供程序打开与工作表的数据库连接。
然后编写简单查询SELECT [Project] FROM [" & wsTable.Name & "$] WHERE [Project] IS NOT NULL GROUP BY [Project];
这将从您在顶部附近设置的工作表中返回不同的项目名称(假设“Project”是字段名称/列标题。
它打开带有该查询的记录集,然后遍历结果,将它们写入VBE中的immediates窗口(随意在此处执行任何操作)。
然后关闭连接并删除工作表。
就像我说的那样,这需要更多参与,但是如果你需要做一些比仅仅变得更加鲜明的事情,这是一条探索的坚实途径......即使你只是变得与众不同,也不是这样如果你不介意代码开销的折衷,那就太糟糕了。
答案 1 :(得分:0)
要循环,一次三个,你可以使用for循环:
Sub test()
Dim intRow as integer
Dim strProject as string
For intRow = 1 to 500 step 3 '1 is starting row, 500 is ending
strProject = Sheet1.Range("B" & intRow).value
Next intRow
End Sub
这似乎是一种很好的方式。我不确定你的自动过滤器的想法是否会起作用,因为它只隐藏了过滤器中未包含的行,因此循环遍历行仍然可以获得所有内容。如果每个项目有时多于或少于三行,您可以遍历每一行并进行测试以确保它们不同:
Sub test()
Dim intRow as integer
Dim strProject as string
For intRow = 1 to 500 '1 is starting row, 500 is ending
if strProject <> Sheet1.Range("B" & intRow).value
strProject = Sheet1.Range("B" & intRow).value
End if
Next intRow
End Sub
这会慢一些,因为它必须遍历每一行并测试它。