2013-02-09 58 views
-1

我是vba編程的新手,因此我需要您的專家幫助,以便能夠使用VBA將以下Excel表中的所有值讀入ADODB記錄集對象2003如何使用VBA 2003動態讀取Excel工作表中的數據

enter image description here 時,該記錄將如下

'Create new recordset with the following fields 
     Dim rsData as new ADODB.Recordset 
     rsData.Fields.Append "Month", adVarChar, 20 
     rsData.Fields.Append "Product", adVarChar, 20 
     rsData.Fields.Append "Type", adVarChar, 50 
     rsData.Fields.Append "Value", adVarChar, 50 
     rsData.Open 


    'for each row in spreadsheet read the following info 
     rsData.Addnew 
      rsData.Fields("Month") = 'value from row 2 Jan followed by data below 
      rsData.Fields("Product") = "Color" ' Value from B5 
      rsData.Fields("Type") = "MK1" ' value from C5 
      rsData.Fields("Value") = "111=" ' value from D6 

'Now move to next set of values for Feb 

    rsData.Addnew 
      rsData.Fields("Month") = 'value from row 2 FEB 
      rsData.Fields("Product") = "Shade" ' Value from F5 
      rsData.Fields("Type") = "AB2" ' value from G5 
      rsData.Fields("Value") = "345=ABX" ' value from H5 

    'Now move to next set of values for Mar 
    rsData.Addnew 
      rsData.Fields("Month") = 'value from row 2 MAR 
      rsData.Fields("Product") = "Color" ' Value from F5 
      rsData.Fields("Type") = "3FG" ' value from G5 
      rsData.Fields("Value") = "PLZ" ' value from H5 

    'Now move to next row 
rsData.Addnew 
      rsData.Fields("Month") = 'value from row 2 Jan 
      rsData.Fields("Product") = "Color" ' Value from F5 
      rsData.Fields("Type") = "MK2" ' value from C6 
      rsData.Fields("Value") = "234=BZX" ' value from D6 

...and so on 

請注意,**的數據可以走動,但整體的佈局保持不變填充。

正如您在下圖中看到的那樣。順序發生了變化:一月,三月,二月**

enter image description here

+1

你需要清楚你的問題。 – Fionnuala 2013-02-09 23:57:23

回答

4

你的問題是不是真的VBA Excel的,問題是,這是一個垃圾數據源。如果塊可以移動並按任意順序排列,那麼確實沒有簡單的方法告訴它們將在哪裏以及它們中包含多少數據。如果是這樣的話,你最好提出以下問題:

  • 源數據是否需要採用此格式;和
  • 有沒有辦法讓我們做得更好?

(「更好」 =更有條理,更可預見。)

而且你想太多的每一行是一個創紀錄的條款。每個塊與其他塊完全分開,並且由於每個塊都有一個唯一的「標題記錄」(即月份),我傾向於依次處理每個塊,而不是像示例代碼嘗試從一個塊跳到另一個塊去做。

以下內容爲您提供足夠的基礎,使您能夠瀏覽Excel工作表。這只是我很快就匆匆而過,並沒有防彈的東西,雖然我在第二張插圖中用一張模擬圖來測試它,但它確實奏效。它應該足以幫助您設置正確的課程,但我再次強調......您擁有的不是真正的數據源。這是一個需要幾乎任意解析的報告。你需要看看在做任何事之前是否可以解決這個問題。

Sub DemonstrateReadingFromExcel() 

'Every cell in Excel is a range. 
'A range can also be a collection of cells. 
'Ranges have properties that you can query. More importantly 
'you can redefine a range by offsetting it from 
'your current range, which makes it easy to step through a block. 
Dim rng_Month As Excel.Range 
Dim rng_Data As Excel.Range 

'Let's define some string variables that you can use to assign 
'to your recordset's fields. 
Dim s_Month As String 
Dim s_Product As String 
Dim s_Type As String 
Dim s_Value As String 

Dim l_RowCurrent As Long 
Dim l_RowLastType As Long 

Dim l_ColumnOfMonth As Long 

'We have to start with the cell containing the month. 
'Rather than reading row by row, you'd be better off 
'reading a whole block at a time. 

'Your big problem will be telling WHERE the cell containing 
'that month is and for that reason I think you need to seriously 
'look at WHY the data is in the format that it is and whether 
'you can actually use a much more structured data source. 

'For now though let's pretend that you have some magic way of knowing 
'where the range is and assign it to a range variable. 

'ActiveSheet is a reference to the active worksheet but just as you 
'can use a range variable to store a reference to a range, 
'you can use a worksheet variable to store a reference to a worksheet 
'(even one which is not the active sheet) if you want to. 
'I'm only using ActiveSheet for convenience. 

'You need to use the Set statement because you're assigning an object. 

Set rng_Month = ActiveSheet.Range("C2") 

'Ranges have properties like their column number. 
'We already know the column number for this range but let's 
'assume that we don't in a more general solution. 

l_ColumnOfMonth = rng_Month.Column 

'Now let's check that the range is valid. 
'Don't worry about what the number means, 
'just look at the error description. 
'If this is True then there must be something wrong with the range. 

If l_ColumnOfMonth < 2 Then 
    Err.Raise vbObjectError + 20000, , "There are no columns to the left of the month. " _ 
    & "The range is invalid." 
End If 

'Now let's find out where the last Type entry occurs in the current 
'block. We go up from the bottom of the column to do that. 

'In this case we're passing the row and column to the Cells 
'property. This defines a range for us representing the bottom 
'of the Type column. Using End(xlUp) is the same as pressing the 
'[End] key then the [Up arrow] key. It takes us to the last 
'populated row, which we read the .Row property of. 

l_RowLastType = ActiveSheet.Cells(_ 
ActiveSheet.Rows.Count, l_ColumnOfMonth).End(xlUp).Row 

'If this is the same as the Month's own row, there's no data 
'in that block. 

If l_RowLastType = rng_Month.Row Then 
    Err.Raise vbObjectError + 20000, , "There are no Type entries in this block. " 
End If 

'So we've checked that the range looks OK. 
'Before we proceed, let's store the month for this block. 
'We just get the Value property of the range. 
s_Month = rng_Month.Value 

'We know that the first product should be 3 rows down and 
'one row to the left of the month, so let's just keep looping 
'through and reading the values for each row in the block 
'until we reach the end of it. We know the end because 
'we have its row stored in the l_RowLastType variable. 

Set rng_Data = rng_Month.Offset(3, -1) 

'Let's get the name of the first product. 
s_Product = rng_Data.Value 

'If that's nothing, there's a problem. 
If s_Product = "" Then 
    Err.Raise vbObjectError + 20000, , "No valid product in the expected location. " 
End If 

'Now let's loop through each row. 
For l_RowCurrent = rng_Month.Row + 3 To l_RowLastType 

    'Let's look at another way that we can get a reference to 
    'a range; by using the Cells property of the sheet. 
    'For that we specify the row number and column number. 

    Set rng_Data = ActiveSheet.Cells(l_RowCurrent, rng_Month.Column - 1) 

    'We know that there won't be a product on each row, 
    'so if there isn't one we just use the previous one. 
    'Otherwise we assign the new product. 

    If rng_Data.Value <> "" Then 
     s_Product = rng_Data.Value 
    End If 

    'Now let's get the type, which is offset 0 rows, 1 column 
    'to the right of the product. 
    s_Type = rng_Data.Offset(0, 1) 

    'If that's a blank cell (like row 8 in your 
    'second example we won't do anything else. 
    'We only proceed if it's populated. 

    If s_Type <> "" Then 
     s_Value = rng_Data.Offset(0, 2) 

     'Now at this point you have gathered all of your values 
     'into variables, and can feed them to your recordset. 
     'In this case though we'll just output 
     'a messagebox. 

     MsgBox "Row " & rng_Data.Row & " is for month " & s_Month _ 
     & ", product " & s_Product & ", Type " & s_Type _ 
     & ", Value " & s_Value 

    End If 

Next 

ExitPoint: 

On Error Resume Next 
Set rng_Month = Nothing 
On Error GoTo 0 

Exit Sub 

ErrorHandler: 

MsgBox "Error " & Err.Number & vbCrLf & Err.Description 

Resume ExitPoint 

End Sub 
+0

你是一個傳奇! – Fraiser 2013-02-10 18:44:11

相關問題