把excel、txt當數據庫來查詢


Sub excel連接數據庫()

    Dim Con As New ADODB.Connection
    Dim strCon, strsql As String
    Dim rs As ADODB.Recordset  '設置記錄集
    Dim i, t, path_
    
    path_ = ThisWorkbook.path & "\"
    
    t = Timer
    
連接字符串 strCon = "Provider=Microsoft.Ace.OLEDB.12.0;Extended Properties='Excel 12.0;imex=0';Data Source=F:\new\v5\11.xlsx"
                                      關聯多個文件查詢 ' strsql = "select a.id,a.firstname,b.lastname from [a1$] a left join [Excel 8.0;hdr=1;imex=1;Database=C:\Users\Administrator\Desktop\a2.xlsx].[a2$] b on a.id=b.id"
表名的表示方式 [] 中括號包起來,里面是sheet名稱+$符號 ' strsql = "select a.id,a.firstname,b.lastname from [EDM-10$] a left join [a2$] b on a.id=b.id" 有些數字查出來后會變成 1900-01-10 12:00:00,看起來是個日期,處理方式就是*1,讓它重新變回數字 strsql = "select a.內部訂單號,a.R * 1 from [CNC-11$] a where a.內部訂單號 <> '內部訂單' "

各種函數的使用,還可以嵌套,但是要注意嵌套的先后順序,比如這個distinct,要達到真正的效果,就得在最外層
'  strsql = " select distinct(UCASE(trim(a.D))) as id from [G-10$] a where a.D <> '內部訂單' "
結果集合並,就是一個累加行的過程
'    strsql = ""
'    strsql = strsql + " select distinct(UCASE(trim(a.D))) as id from [EDM-10$] a where a.D <> '內部訂單' "
'    strsql = strsql + " union "
'    strsql = strsql + " select distinct(UCASE(trim(a.D))) as id from [G-10$] a where a.D <> '內部訂單' "
   
    Con.Open strCon
    
    Set rs = Con.Execute(strsql)

這個是查詢所有sheet的名字
' Set rs = Con.OpenSchema(20) 'adSchemaTables=20 ' Columns("A:A").NumberFormatLocal = "m""月""d""日"";@" For i = 0 To rs.Fields.Count - 1 Sheets("lcx").Cells(1, i + 1) = rs.Fields(i).Name Next i Sheets("lcx").Cells(2, 9).CopyFromRecordset rs rs.Close Con.Close Set rs = Nothing Set Con = Nothing Debug.Print "提取完畢" & "耗時" & Round(Timer - t, 4) & "" End Sub

 需要引用的project有3個:

 補充

Sub lcxreaddata()

    Dim fname As String, path As String, cnn As Object, rst As ADODB.Recordset, sql As String
    
使用createobject的方式,不需要引入相應的project,可以直接使用 Set cnn
= CreateObject("ADODB.Connection") fname = "11.xlsx" path = "F:\new\v5\" & fname cnn.Open "Provider=Microsoft.Ace.OLEDB.12.0;Extended Properties='Excel 12.0;imex=0';Data Source=" & path
$符號后面可以加查詢的范圍
' sql = "SELECT [Actual],[Upper Tol] FROM [Report$a13:f100] where Characteristic='" & cname & "'"
有特殊符號的字段,用中括號括起來就可以使用了,否則需要打開表替換字段名稱,關閉的時候還要還原,是不是好傻的操作,都怪以前沒有get到這個技能 ' sql
= " SELECT [新模/修模],[實際產出(H)] FROM [CNC-11$a:r] where [實際產出(H)] <> 0 "
where后面的條件匹配要注意類型,字符串類型的字段用字符串匹配,數字類型的列用數字匹配,否則會報類型不匹配的錯誤,還有就是,如果兩個表關聯查詢的時候,兩個關聯的字段的類型必須一致,否則也會報類型不匹配的錯誤 sql
= " SELECT [新模/修模],[實際產出(H)] FROM [CNC-11$a:r] where trim([新模/修模]) <> '' " Set rst = cnn.Execute(sql) Sheets.Add For i = 0 To rst.Fields.Count - 1 Cells(1, i + 1) = rst.Fields(i).Name Next i Cells(2, 1).CopyFromRecordset rst cnn.Close Set rst = Nothing Set cnn = Nothing End Sub

 'excel 8.0;hdr=no',此設置決定沒有字段名,設置hdr=no時,默認標題字段為F1,F2…………

 

將EXCEL文件作為數據庫連接,實際並不打開EXCEL,

Excel2003版本:cnn.Open "Provider=Microsoft.jet.OLEDB.4.0;Extended Properties=Excel 8.0;Data Source=" & ThisWorkbook.Path & "\數據表.xls"

Excel2007版本:cnn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0;Data Source=" & ThisWorkbook.Path & "\數據表.xlsx"

帶參數的連接字符串:cnn.Open "provider=microsoft.jet.oledb.4.0;extended properties='excel 8.0;HDR=yes;IMEX=2';data source=" & ThisWorkbook.FullName

HDR=Yes 代表 Excel 檔中的工作表第一行是標題欄,標題只能是一行,不能使多行,或者合並的單元格。

HDR=no 工作表第一行就是數據了,沒有標題欄,不使用欄位,則欄位就以f代表,第一列列名就是:f1,第二列列名:f2

IMEX 匯入模式 0 只讀 1 只寫 2 可讀寫

當 IMEX=0 時為“匯出模式”,這個模式開啟的 Excel 檔案只能用來做“寫入”用途。
當 IMEX=1 時為“匯入模式”,這個模式開啟的 Excel 檔案只能用來做“讀取”用途。
當 IMEX=2 時為“連結模式”,這個模式開啟的 Excel 檔案可同時支援“讀取”與“寫入”用途。

Data Source 存儲查詢數據來源的工作薄名稱,數據庫路徑為:數據表.xls 或本表:& ThisWorkbook.FullName

oledb也能將txt當數據庫來查詢

Sub 讀count_個數求和后寫入sum(fpath, fname, sumfile)
    
    Call CreateSchema(fpath, fname, "false", 6)
    
    Dim cn As Object, rs As Object
    
    Dim strsql As String
     
    Set cn = CreateObject("ADODB.Connection")

    cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties='text;';Data Source=" & fpath
    
    strsql = " select f1,f2,f3,f4,f5,sum(f6) from [" & fname & "] group by f1,f2,f3,f4,f5 order by f1*1,f2*1,f3*1,f4*1,f5*1 "
    
    Set rs = cn.Execute(strsql)
    
    sumfile.Write "列1" & vbTab & "列2" & vbTab & "列3" & vbTab & NW & "個數" & vbTab & ML & "個數" & vbTab & "數量"
    sumfile.WriteLine rs.GetString(, , , vbCrLf)

 這個一定要記得關,否則當txt數據量龐大的時候,比如我測試的時候,用的3個50萬行數據的txt,一個一個按順序讀,如果不關,就會很卡,關了就會很順暢 rs.Close cn.Close Set rs = Nothing Set Con = Nothing
    
    Call KillSchema(fpath)
    
End Sub

 

Sub CreateSchema(fpath, fname, hdr, cc)

    Dim fso, MyFile, i
    
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    Set MyFile = fso.CreateTextFile(fpath & "\schema.ini", True)
    
    MyFile.WriteLine "[" & fname & "]"
    MyFile.WriteLine "COLNAMEHEADER = " & hdr
    MyFile.WriteLine "Format = TabDelimited"
    
    For i = 1 To cc
        MyFile.WriteLine "Col" & i & " = f" & i & " Char"
    Next
    
    MyFile.Close
    
    Set fso = Nothing
    
End Sub


Sub KillSchema(fpath)

    Kill fpath & "\schema.ini"
    
End Sub

 

如果是標准逗號隔開的txt文件,直接用下面的連接字符串就可以了,就不用寫schema.ini文集了

cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties='text;IMEX=1;HDR=NO;FMT=Delimited;';Data Source=" & ThisWorkbook.Path

 

schema.ini文件可以定義字段類型,分隔符符號等,在同目錄下要建一個Schema.ini說明txt文件的數據格式,例:

[code=INIFile]
[customers.txt]
Format=TabDelimited
ColNameHeader=True
MaxScanRows=0 CharacterSet=ANSI
characterset默認就是ansi,所以也可以不用指定
[orders.txt] Format
=Delimited(;) ColNameHeader=True MaxScanRows=0 CharacterSet=ANSI [invoices.txt] Format=FixedLength ColNameHeader=False Col1=FieldName1 Integer Width 15 Col2=FieldName2 Date Width 15 Col3=FieldName3 Char Width 40 Col4=FieldName4 Float Width 20 CharacterSet=ANSI[/code]

 

再說一個查詢結果寫入txt的示例

Sub 讀count_個數求和后寫入sum(fpath, fname, sumfile)
    
    Call CreateSchema(fpath, fname, "false", 6)
    
    Dim cn As Object, rs As Object
    
    Dim strsql As String
     
    Set cn = CreateObject("ADODB.Connection")

    cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties='text;';Data Source=" & fpath
    
    strsql = " select f1,f2,f3,f4,f5,sum(f6) from [" & fname & "] group by f1,f2,f3,f4,f5 order by f1*1,f2*1,f3*1,f4*1,f5*1 "
    
    Set rs = cn.Execute(strsql)
    
rs.getstring有多個參數,分別是:
rs.GetString(StringFormat,NumRows,ColumnDelimiter,RowDelimiter,NullExpr)
默認的換行符是\n,但是txt的換行符是\r\n,所以如果不設置一下RowDelimiter,打開txt就不會有換行的效果,word打開的話是有換行效果的,word里\n是被識別的

表頭用write不用writeline,是因為用writeline會多出一個空行,我估計是因為rs返回的字符串,首行前可能有換行符吧,具體的也沒有去研究
sumfile.Write
"列1" & vbTab & "列2" & vbTab & "列3" & vbTab & "列4" & vbTab & "列5" & vbTab & "列6" sumfile.WriteLine rs.GetString(, , , vbCrLf) rs.Close cn.Close Set rs = Nothing Set Con = Nothing Call KillSchema(fpath) End Sub

 

有很多方式讀寫數據,但是發現的最快的方式,就是sql,具體為什么,也沒有去研究過

還有就是 Microsoft.jet.OLEDB.4.0;Microsoft.ACE.OLEDB.12.0; 兩種連接,我的電腦都是支持的,但是有個別電腦不支持jet4.0的,具體原因我也沒有去研究過

這些我沒有研究過的地方,如果有哪位大神知道的,還望能解答迷惑

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM