简体   繁体   English

到 Recordset 的不连贯范围

[英]Incoherent Range into Recordset

I got a problem with the Recordset I'm using in my Excel VBA Project.我在 Excel VBA 项目中使用的记录集出现问题。 I'm trying to read a certain range into the Recordset and til now it always worked.我正在尝试将某个范围读入 Recordset,直到现在它始终有效。 But this time around I want to get a incoherent range, which in my case consists of columns of a table, and give this range to the recordset through the following function (got it from @Martin Dreher)但是这一次我想获得一个不连贯的范围,在我的例子中它由表的列组成,并通过以下函数将此范围提供给记录集(从@Martin Dreher 获得)

'this is how I set the range
Set SourceRange = ThisWorkbook.Worksheets(1).Range("Tablename[[field1]:[field2]], " & _
    "Tablename[[field3]:[field4]], Tablename[[field5]:[field6]]")

'this is the function I set my recordset with
Function GetRecordset(rng As Range)

    Dim xlXML       As Object
    Dim rst         As Object

    Set rst = CreateObject("ADODB.Recordset")
    Set xlXML = CreateObject("MSXML2.DOMDocument")
    xlXML.LoadXML Replace(rng.Value(xlRangeValueMSPersistXML), "rs:name="" ", "rs:name=""")
    rst.Open xlXML

    Set GetRecordset = rst

End Function

When I select the range via VBA and it is the one I want but when calling getRecordset and afterwords copy the data out of the recordset all I get is the data of the first range.当我通过 VBA 选择范围并且它是我想要的范围时,但是当调用 getRecordset 和后记将数据从记录集中复制出来时,我得到的只是第一个范围的数据。

I edited the names of the variables since there is some internal data involved.我编辑了变量的名称,因为涉及到一些内部数据。

Thanks already for your help!已经感谢您的帮助!

Glad you found it useful.很高兴你发现它有用。 Please make sure to mark helpful answers and close open threads, if you consider the problem solved.如果您认为问题已解决,请确保标记有用的答案并关闭开放线程。

On topic:主题:

Add Debug.Print rng.value(xlRangeValueMSPersistXML) inside your function for debugging.在您的函数中添加Debug.Print rng.value(xlRangeValueMSPersistXML)以进行调试。 You'll see that the XML only contains your first range, even if you union your ranges with, well, Union first.您会看到 XML 只包含您的第一个范围,即使您将范围与,好吧, Union优先。

Afaik there's no fix for this. Afaik 没有办法解决这个问题。 Try to fix with continuous ranges.尝试使用连续范围进行修复。

However, if you absolutely need two ranges in one recordset, and you can guarantee they have both the same number of rows and that each Row(i) in A belongs to Row(i) in B , then a workaround would be to但是,如果你绝对需要两个范围的一个记录,并且可以保证他们有两个相同的行数和每Row(i)A属于Row(i)B ,那么解决方法是

  • create a new sheet on the fly with With ThisWorkbook.Worksheets.Add使用With ThisWorkbook.Worksheets.Add即时创建新工作表
  • output your Union -range-values to that sheet in a continuous range starting at .Cells(1,1)在从.Cells(1,1)开始的连续范围内将您的Union范围值输出到该工作表
  • retrieve the XML from pass .UsedRange从 pass .UsedRange检索 XML
  • read the XML into your recordset将 XML 读入您的记录集中
  • .Delete the worksheet with no prompts .Delete没有提示的工作表
  • End with End withEnd with

Put this into your GetRecordset -Function, since, at the same time, it solves the problem you had with two header rows.将其放入您的GetRecordset -Function 中,因为它同时解决了您在使用两个标题行时遇到的问题。 If performance is an issue, consider passing an additional Boolean to your function to determine if your function uses the workaround or not.如果性能是一个问题,请考虑向您的函数传递一个额外的Boolean ,以确定您的函数是否使用该解决方法。

Hope that helps.希望有帮助。

Edit: We cannot just delete an unused Field from an open recordset.编辑:我们不能只是从打开的记录集中删除一个未使用的Field As you might expect, every workaround is a bit dirty.正如您所料,每个解决方法都有点脏。

Since I would have to test performance, I can only give you some ideas for testing.由于我要测试性能,我只能给你一些测试的想法。

  1. with the use of Worksheets.Add mentioned above, a slower performance is to be expected if you do it repeatedly.使用上面提到的Worksheets.Add ,如果重复执行,性能会降低。

    However, instead of creating a Worksheet in each loop, you could但是,不是在每个循环中创建一个Worksheet ,您可以

    • create a new Worksheet once,一次创建一个新的Worksheet
    • .UsedRange.Cells.Clear after each iteration .UsedRange.Cells.Clear每次迭代后
    • .Delete once at the end. .Delete一次。
  2. if you use .CopyFromRecordset , and start with blank output-sheets, it's likely faster to just如果您使用.CopyFromRecordset并从空白输出表开始,则可能会更快

    • loop Cells in Rows(1) of your Ouput在输出的Rows(1)中循环Cells
    • if the header is in your "unwanted"-list then .EntireColumn.Delete如果标题在您的“不需要的”列表中,则.EntireColumn.Delete

I would give 1. a try.我会给 1. 试一试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM