利用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

相关文章
相关标签/搜索