利用ADO讓普通人用excel讀取oracle數據庫表的通用辦法

Ref:http://blog.csdn.net/iamlaosong/article/details/8465177mysql

 

Excel經過ADO方式鏈接到Oracle並操做Oracle給那些編程能力不強的人帶來很大的福音,結合着Excel的數據處理與圖表製做,就能很輕鬆地處理一些常規工做。sql

平常工做中須要查詢各類數據,並且不斷變化,處理這些數據的人不是技術人員,不會鏈接數據庫本身查詢,經過下面的辦法就可讓技術人員編輯好包含查詢語句的excel文件,讓管理人員本身輸入條件取數了。數據庫

 

個人方法是編輯須要的SQL語句保存在單元格中,並在查詢條件須要參數值的地方用問號「?」代替,再在其餘單元格中保存查詢條件所需的參數值,在「宏」中用參數值替換掉SQL語句中的問號,最後執行查詢語句並將結果保存到excel表中。編程

 

如下是經過Excel的VBA鏈接Oracle並讀取Oracle相關數據的步驟:服務器

  一、引用ADO相關組件:oracle

打開VBA編輯器,在菜單中點選「工具」--》「引用」。確保「Microsoft ActiviteX Data Objects 2.8 Library」和「Microsoft ActiviteX Data ObjectS Recordset 2.8 Library」被勾選上。編輯器

  二、創建讀取數據的過程:ide

 

[vb]  view plain  copy
 
 
  1. Public Sub get_data()  
  2.     '根據工做表中的查詢語句讀取數據  
  3.     On Error GoTo ErrMsg:  
  4.       
  5.     Dim cnn As Object, rst As Object  
  6.     Dim name, stat, sqls, field As String  
  7.     Dim pn(4), pm(4) As String  
  8.     Dim i, j, kk, pmkk, lineno As Integer  
  9.     Dim OraOpen As Boolean  
  10.       
  11.     Set cnn = CreateObject("ADODB.Connection")  
  12.     Set rst = CreateObject("ADODB.Recordset")  
  13.     sqls = "connect database"  
  14.     cnn.Open "Provider=msdaora;Data Source=dl580;User Id=sxjkuser;Password=sxjkpasswd;"  
  15.     OraOpen = True '成功執行後,數據庫即被打開  
  16.       
  17.     If OraOpen Then lineno = [D65536].End(xlUp).Row Else lineno = 0       '行數  
  18.       
  19.     Application.Calculation = xlManual  
  20.     For i = 3 To lineno  
  21.         stat = Trim(Cells(i, 3))  
  22.           
  23.         If stat = "Y" Or stat = "y" Then  
  24.             name = Cells(i, 2)  
  25.             field = Cells(i, 4)  
  26.             pn(1) = Cells(i, 5)  
  27.             pm(1) = Cells(i, 6)  
  28.             pn(2) = Cells(i, 7)  
  29.             pm(2) = Cells(i, 8)  
  30.             pn(3) = Cells(i, 9)  
  31.             pm(3) = Cells(i, 10)  
  32.             pn(4) = Cells(i, 11)  
  33.             pm(4) = Cells(i, 12)  
  34.             pmkk = Cells(i, 13)  
  35.             sqls = Cells(i, 15)  
  36.             'MsgBox sqls  
  37.               
  38.             For kk = 1 To pmkk  '用於參數屢次使用,如聯合SQL語句中每一個子句都須要日期參數  
  39.                 For j = 1 To 4  
  40.                     If pn(j) <> "" Then  
  41.                         sqls = Replace(sqls, "?", pm(j), 1, 1)  
  42.                         'MsgBox sqls  
  43.                     End If  
  44.                 Next j  
  45.             Next kk  
  46.             MsgBox sqls  
  47.             Set rst = cnn.Execute(sqls)  
  48.             sqls = "clear sheets"  
  49.             maxrow = Sheets(name).UsedRange.Rows.Count  
  50.             Sheets(name).Range("a2:" & field & maxrow).ClearContents  
  51.             sqls = "CopyFromRecordset"  
  52.             Sheets(name).Range("a2").CopyFromRecordset rst  
  53.             Cells(i, 3) = "成功"  
  54.             'MsgBox i  
  55.         End If  
  56.     Next i  
  57.       
  58.     'rst.Close  
  59.     'Set rst = Nothing  
  60.     cnn.Close  
  61.     Set cnn = Nothing  
  62.       
  63.     Application.Calculation = xlAutomatic  
  64.     'Sheets("分析").PivotTables("數據透視表1").PivotCache.Refresh  
  65.     Worksheets("系統參數").Select  
  66.     msg = MsgBox("數據讀取完畢!", vbOKOnly, "iamlaosong")  
  67.     Exit Sub  
  68. ErrMsg:  
  69.     OraOpen = False  
  70.     MsgBox sqls, vbCritical, "操做失敗 ,請檢查!"  
  71.   
  72. End Sub  


       三、SQL語句實例工具

 

這是一個簡單的語句:.net

 

[sql]  view plain  copy
 
 
  1. SELECT *  FROM zdgc_sn_sj_gfl t  
  2.  WHERE t.CLCT_DATE = to_date('?', 'yyyy-mm-dd')  
  3.    AND t.JSBZ = '1'  
  4.  ORDER BY t.CITY, t.SSXS  


這是一個複雜的語句:

 

 

[sql]  view plain  copy
 
 
  1. select aa.zj_code,  
  2.        aa.zj_mc,  
  3.        aa.clct_date,  
  4.        aa.sjzl,  
  5.        aa.jyqsjzl,  
  6.        nvl(bb.wgfsl, 0),  
  7.        nvl(bb.jyqwgfsl, 0)  
  8.   from (select b.ssxs,  
  9.                b.zj_code,  
  10.                b.zj_mc,  
  11.                a.clct_date,  
  12.                count(*) sjzl,  
  13.                sum(case  
  14.                      when to_char(a.clct_time, 'hh24mi') <= '?' then  
  15.                       1  
  16.                      else  
  17.                       0  
  18.                    end) jyqsjzl  
  19.           from tb_evt_mail_clct a, sncn_zd_jg b  
  20.          where a.clct_bureau_org_code = b.zj_code  
  21.            and a.time_limit_code <> '6'  
  22.            and a.mail_kind_code <> '10401'  
  23.            and a.addi_service_code <> '1'  
  24.            and (a.rcv_area like '23%' or a.rcv_area like '24%')  
  25.          group by b.ssxs, b.zj_code, b.zj_mc, a.clct_date) aa  
  26.   left join (select b.ssxs,  
  27.                     b.zj_code,  
  28.                     b.zj_mc,  
  29.                     a.clct_date,  
  30.                     count(*) wgfsl,  
  31.                     sum(decode(jybz, 'b', 1, 0)) jyqwgfsl  
  32.                from sncn_zd_jg b, zdgc_sn_sj_errfc a  
  33.               where a.zj_code = b.zj_code  
  34.                 and a.jsbz = '1'  
  35.                 and a.jybz = 'b'  
  36.               group by b.ssxs, b.zj_code, b.zj_mc, a.clct_date) bb on aa.ssxs =  
  37.                                                                       bb.ssxs  
  38.                                                                   and aa.zj_code =  
  39.                                                                       bb.zj_code  
  40.                                                                   and aa.clct_date =  
  41.                                                                       bb.clct_date  
  42.  where aa.clct_date = to_date('?', 'yyyy-mm-dd')  
  43.    and aa.ssxs = '?'  
  44.  order by aa.zj_code, aa.zj_mc  


  四、操做界面

 

這是一個:

 

這是另外一個:

 

  五、說明

1)使用者須要安裝Oracle客戶端並進行本地服務名配置(運行客戶端程序Net Configuration Assistant配置,本例配置的服務名是DL580),實際就是配置tnsnames.ora文件。也能夠安裝簡易oracle客戶端,並用記事本修改tnsnames.ora文件,本例就是須要在該文件中增長以下內容(本例Oracle數據庫服務器地址是10.178.10.197,SID是ORCL):

DL580 =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 10.178.10.197)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = orcl)
    )
  )

經過工做表保護使使用者只能修改參數值和狀態,其餘不能修改,防止破壞相關設置。

 

2)能夠用循環實現參數的屢次使用,這在SQL包含多個子查詢,參數是日期的狀況下頗有用,每一個子查詢多會用到參數中的起止日期。循環中若是某個子查詢只用到部分參數,能夠用註釋語句中加「?」的方式站位。例如:

 

[sql]  view plain  copy
 
 
  1. select b.city,  
  2.        b.ssxs,  
  3.        a.clct_bureau_org_code,  
  4.        b.zj_mc,  
  5.        a.sender_cust_code,  
  6.        a.sender_dept_name,  
  7.        min(a.clct_date),  
  8.        max(a.clct_date),  
  9.        count(*) yjzl,  
  10.        sum(a.actual_total_fee) yjsr  
  11.   from tb_evt_mail_clct a,  
  12.        (select * from sncn_zd_jg where jgfl = 'sd') b,  
  13.        (select distinct t.sender_cust_code  
  14.           from tb_evt_mail_clct t  
  15.          where t.clct_date < to_date('?', 'yyyy-mm-dd')) c  
  16. -- ?  佔位  
  17.  where a.clct_bureau_org_code = b.zj_code  
  18.    and a.clct_date between to_date('?', 'yyyy-mm-dd') and  
  19.        to_date('?', 'yyyy-mm-dd')  
  20.    and length(a.sender_cust_code) = 14  
  21.    and a.sender_cust_code = c.sender_cust_code(+)  
  22.    and c.sender_cust_code is null  
  23.  group by b.city,  
  24.           b.ssxs,  
  25.           a.clct_bureau_org_code,  
  26.           b.zj_mc,  
  27.           a.sender_cust_code,  
  28.           a.sender_dept_name  
  29.  order by b.city,  
  30.           b.ssxs,  
  31.           a.clct_bureau_org_code,  
  32.           b.zj_mc,  
  33.           a.sender_cust_code,  
  34.           a.sender_dept_name  
 



 

 

附:簡易客戶端(版本9i)資源下載地址:http://download.csdn.net/detail/iamlaosong/5035733

       完整的工具包(含Oracle簡易客戶端資源下載地址:http://download.csdn.NET/detail/iamlaosong/5307186

相關文章
相關標籤/搜索