Excel精英培训网

 找回密码
 注册
数据透视表40+个常用小技巧,让你一次学会!
查看: 4792|回复: 11

[已解决]SQL查询数据,导出到Excel

[复制链接]
发表于 2015-7-1 08:34 | 显示全部楼层 |阅读模式
231714zdeqq939gizxs9xi.gif
如何获取最大五户.rar (27.35 KB, 下载次数: 10)
excel精英培训的微信平台,每天都会发送excel学习教程和资料。扫一扫明天就可以收到新教程
发表于 2015-7-1 09:27 | 显示全部楼层
本帖最后由 roych 于 2015-7-1 09:34 编辑

sql语句写错了,应该是:
sql = "select top 5 工资,姓名 from (select * from [Sheet1$a:d] where 员工类型='一类' order by 工资 desc)"
或者更简单点:
sql = "select top 5 工资,姓名 from  [Sheet1$a:d] where 员工类型='一类' order by 工资 desc"

顺便说一句,你的表格式有问题。怎么会有两列工资的呢?而且B列还是数值文本混排的(很可能无法读取部分数据)……
删除B列后,使用上面的sql语句来运行即可。
回复

使用道具 举报

 楼主| 发表于 2015-7-1 09:51 | 显示全部楼层
roych 发表于 2015-7-1 09:27
sql语句写错了,应该是:
sql = "select top 5 工资,姓名 from (select * from [Sheet1$a:d] where 员工类 ...

谢谢roych!

是这样的,开始我想直接实现做sheet1的i3:j7里的效果,所以写成
select top 5 工资,姓名 from (select * from [Sheet1$a:d] where 员工类型='一类' order by 工资 desc) order by 工资 asc

但测试后发现找出的结果不同了,于是想保证结果对了就算了,所以才省略了最后的排序,忘了改成你2楼的语句。
select top 5 工资,姓名 from (select * from [Sheet1$a:d] where 员工类型='一类' order by 工资 desc)

为什么省略了最后的排序,结果就错呢?这问题我没找到原因,也正想学习。。。。



回复

使用道具 举报

 楼主| 发表于 2015-7-1 09:54 | 显示全部楼层
roych 发表于 2015-7-1 09:27
sql语句写错了,应该是:
sql = "select top 5 工资,姓名 from (select * from [Sheet1$a:d] where 员工类 ...

怎么会有两列工资的呢?

是不是你运行代码后的结果?要不先不管代码,只操作测试

怎么修改SQL语句?才能和sheet1的i3:j7的效果一样。
回复

使用道具 举报

发表于 2015-7-1 10:51 | 显示全部楼层    本楼为最佳答案   
本帖最后由 roych 于 2015-7-1 11:52 编辑
爱疯 发表于 2015-7-1 09:51
谢谢roych!

是这样的,开始我想直接实现做sheet1的i3:j7里的效果,所以写成

先来说说test3的问题:
1、top 5只按第一个字段来排序的,而且默认的话是升序,因此要加上desc才能降序排列。
2、如果需要按姓名,工资的字段列出来的话,嵌套一下即可。——嵌套后工资仍然是降序的,还是要order by一下才能升序排列:
sql = "select 姓名,工资 from (select top 5 工资,姓名 from  [Sheet1$a:d] where 员工类型='一类' order by 工资 desc) as A order by 工资"
——虽然不一定非要用别名A,不过我习惯上喜欢用别名。这时候也可以升序
再来说说test2,也就是按钮的问题:
1、跨表操作的话,不能这样写的:
Range("A2").CopyFromRecordset rs    '记录集
而应该改为:
sheets(x).Range("A2").CopyFromRecordset rs    '记录集
2、虽然test2放在sheet1里是没问题的。不过,强烈建议把这种跨表的模块放在模块级别(而不是工作表级别)上,这样就是公共模块了,调用起来就不必考虑太多。详细见附件:
如何获取最大五户.rar (26.25 KB, 下载次数: 9)

评分

参与人数 1金币 +8 收起 理由
爱疯 + 8 赞一个!

查看全部评分

回复

使用道具 举报

发表于 2015-7-1 11:01 | 显示全部楼层
模块一

Option Explicit
'例2:查询数据,导出到Excel
Sub test2(x, y)
    Dim con, rs, sql$, i%

    '1)引用ADO对象,以下是后期绑定的方式
    Set con = CreateObject("adodb.connection")  '建立ADO连接对象
    Set rs = CreateObject("adodb.recordset")   '建立ADO记录集对象

    '2)创建连接
    '已连接

    '3)建立连接
    con.Open "provider=microsoft.ace.oledb.12.0;extended properties=excel 12.0;data source=" & ThisWorkbook.FullName

    '4)编辑SQL
    sql = "select top 5 姓名,工资 from (select * from [Sheet1$a:d] where 员工类型='" & y & "' order by 工资 desc)"

    '5)执行SQL
    Set rs = con.Execute(sql)       '存入Recordset对象
    '    MsgBox IIf(rs.BOF And rs.EOF, "没记录", "有记录")

    '6)导入工作簿
    Sheets(x).Activate
    Sheets(x).Cells.Clear
    For i = 0 To rs.Fields.Count - 1    '字段
        Cells(2, i + 1) = rs.Fields(i).Name
    Next
    Range("A3").CopyFromRecordset rs    '记录集
    Range("A1") = y & "员工前五名"   '填写标题
    Range("A1:B7").Borders.LineStyle = xlContinuous  '添加边框
    Range("A1:B1").Merge '合并标题栏
    Range("A1").HorizontalAlignment = xlCenter '标题居中
    '7)关闭连接,释放对象
    rs.Close: Set rs = Nothing
    con.Close: Set con = Nothing
End Sub


Sheet 1
Option Explicit

Private Sub CommandButton1_Click()
    Call test2(2, "一类")
    Call test2(3, "二类")
End Sub

评分

参与人数 1金币 +5 收起 理由
爱疯 + 5 赞一个!

查看全部评分

回复

使用道具 举报

 楼主| 发表于 2015-7-1 11:26 | 显示全部楼层
roych 发表于 2015-7-1 10:51
先来说说test3的问题:
1、top 5只按第一个字段来排序的,而且默认的话是升序,因此要加上desc才能降序排 ...

1)top 5只按第一个字段来排序的
学习了,果真如此。

下句是我原来出错,放弃的语句
select 姓名,工资 from (select top 5 工资,姓名 from  [Sheet1$a:d] where 员工类型='一类' order by 工资 desc) as A order by 工资

外层的字段名修改位置后,就对了。
select 工资,姓名 from (select top 5 工资,姓名 from  [Sheet1$a:d] where 员工类型='一类' order by 工资 desc) as A order by 工资

不过还是你那样好点,因为更接近最终效果。
top 5 放在里层或外层,都一样。


2)sheets(x).Range("A2").CopyFromRecordset rs
为何前面有 Sheets(x).Activate,仍发现选错工作表 ......?如果能知道原因就更好了。
回复

使用道具 举报

 楼主| 发表于 2015-7-1 11:28 | 显示全部楼层
ssdboy 发表于 2015-7-1 11:01
模块一

Option Explicit

谢谢ssdboy

因为我只是为了来学习,谢谢你的指正!
回复

使用道具 举报

发表于 2015-7-1 11:55 | 显示全部楼层
本帖最后由 roych 于 2015-7-1 12:02 编辑
爱疯 发表于 2015-7-1 11:26
1)top 5只按第一个字段来排序的
学习了,果真如此。

只是把第一类跟第二类放在了sheet2跟sheet3上,是跟你给的结果是一致的呀。
如果用copyfromrecordset是会覆盖掉格式的。如果要保留格式的话,可以预先设置好格式,然后用这样的语句写入:
do until rst.eof
'如果字段比较多的话,这部分也可以用循环来写
    sheets(2).range("A2").offset(i,0)=rst(0)
    sheets(2).range("A2").offset(i,1)=rst(1)
     i=i+1
    rst.movenext
loop
此外,就是跟前面一个版友那样,把数据复制完成后再设置
test.gif
回复

使用道具 举报

 楼主| 发表于 2015-7-1 15:31 | 显示全部楼层
roych 发表于 2015-7-1 11:55
只是把第一类跟第二类放在了sheet2跟sheet3上,是跟你给的结果是一致的呀。
如果用copyfromrecordset是会 ...

QQ截图20150701151334.jpg
如何获取最大五户2.rar (29.19 KB, 下载次数: 1)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|Excel精英培训 ( 豫ICP备11015029号 )

GMT+8, 2024-5-11 03:24 , Processed in 0.255463 second(s), 13 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表