今天周末,突然感觉好久没练窗体了
恰好在群里潜水看到有网友咨询如何跨工作簿复制指定工作表到当前表的问题
为此,小编用SQL结合窗体做了个查询工具,但是使用SQL只能返回记录的值,如果需要把原表的公式,格式等复制过来,就需要用到workbook的方法了,关于WorkBook(工作簿)WorkSheet(工作表)我们以后往下练习
先看下SQL的效果,如下图所示

画的有点丑..

窗体代码如下
Option ExplicitPrivate Sub CommandButton1_Click() '获取路径Dim strPath$With Application.FileDialog(msoFileDialogFilePicker)If .Show ThenstrPath = .SelectedItems(1)ElseExit SubEnd IfEnd WithMe.TextBox1.Text = strPathEnd SubPrivate Sub CommandButton2_Click() '代码执行Dim strSQL$, S$, intX&, YesNo&Dim Conn As Object, Rec As ObjectDim aField, strConn$On Error Resume NextSet Conn = CreateObject("Adodb.Connection")If Application.Version < 12 Then '判断Excel的版本号,以使用不同的连接字符串Conn.Open "Provider=Microsoft.ACE.OLEDB.4.0;Extended Properties='Excel 8.0;HDR=yes;IMEX=0';Data Source=" & Me.TextBox1.TextElseConn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties='Excel 12.0;HDR=yes;IMEX=0';Data Source=" & Me.TextBox1.TextEnd IfWith MeIf .ListBox3.ListCount = 0 ThenstrSQL = "Select * From [" & .ListBox1.Text & "]"ElseFor intX = .ListBox3.ListCount - 1 To 0 Step -1S = S & ",[" & .ListBox3.List(intX) & "]"NextstrSQL = "Select " & Mid(S, 2) & " From [" & .ListBox1.Text & "]"End IfEnd WithSet Rec = Conn.Execute(strSQL)ReDim aField(1 To Rec.Fields.Count)For intX = 0 To Rec.Fields.Count - 1aField(intX + 1) = Rec.Fields(intX).NameNextYesNo = MsgBox("是否覆盖本表", vbYesNo, "Excel VBA练习提示!!")If YesNo = 7 ThenSheets.Add after:=Sheets(Sheets.Count)End IfWith ActiveSheet.Cells.Clear.Range("A1").Resize(, UBound(aField)) = aField.Range("A2").CopyFromRecordset Rec.Columns.AutoFit.UsedRange.Borders.LineStyle = 1End WithConn.CloseSet Rec = NothingSet Conn = NothingMe.ListBox3.ClearCall Update_Field '更新下End SubPrivate Sub CommandButton3_Click() '选择Dim intX&With MeIf .ListBox2.ListIndex = -1 Then Exit Sub '未选择则退出With .ListBox2For intX = .ListCount - 1 To 0 Step -1If .Selected(intX) ThenMe.ListBox3.AddItem .List(intX).RemoveItem (intX)End IfNextEnd WithEnd WithEnd SubPrivate Sub CommandButton4_Click() '取消Dim intX&With MeIf .ListBox3.ListIndex = -1 Then Exit Sub '未选择则退出With .ListBox3For intX = .ListCount - 1 To 0 Step -1If .Selected(intX) ThenMe.ListBox2.AddItem .List(intX).RemoveItem (intX)End IfNextEnd WithEnd WithEnd SubPrivate Sub ListBox1_Click() '点击工作表更新字段Call Update_FieldEnd SubSub Update_Field() '字段更新Dim Rec As Object, Conn As ObjectDim strSQL$, intX&On Error Resume NextSet Conn = CreateObject("Adodb.connection")Set Rec = CreateObject("adodb.recordset")If Application.Version < 12 Then '判断Excel的版本号,以使用不同的连接字符串Conn.Open "Provider=Microsoft.ACE.OLEDB.4.0;Extended Properties='Excel 8.0;HDR=yes;IMEX=0';Data Source=" & Me.TextBox1.TextElseConn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties='Excel 12.0;HDR=yes;IMEX=0';Data Source=" & Me.TextBox1.TextEnd IfstrSQL = "select * from [" & Me.ListBox1.Text & "]"Rec.Open strSQL, Conn, 1, 3With Me.ListBox2.ClearFor intX = 0 To Rec.Fields.Count - 1.AddItem Rec.Fields(intX).NameNextEnd WithSet Conn = Nothing: Set Rec = NothingEnd SubPrivate Sub TextBox1_Change() '路径改变发生的事件Dim Conn As Object, Rec As ObjectOn Error Resume NextMe.ListBox2.ClearMe.ListBox3.ClearSet Conn = CreateObject("adodb.connection")If Application.Version < 12 Then '判断Excel的版本号,以使用不同的连接字符串Conn.Open "Provider=Microsoft.ACE.OLEDB.4.0;Extended Properties='Excel 8.0;HDR=yes;IMEX=0';Data Source=" & Me.TextBox1.TextElseConn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties='Excel 12.0;HDR=yes;IMEX=0';Data Source=" & Me.TextBox1.TextEnd IfSet Rec = Conn.openschema(20)With Me.ListBox1.ClearDo Until Rec.EOFIf Rec!TABLE_TYPE = "TABLE" ThenIf Right(Rec!TABLE_NAME, 1) = "$" Then.AddItem Rec!TABLE_NAMEEnd IfEnd IfRec.MoveNextLoopEnd WithEnd SubPrivate Sub UserForm_Initialize() '加载窗体初始化With Me.TextBox1.Text = ThisWorkbook.FullNameWith .ListBox2.MultiSelect = fmMultiSelectMulti.ListStyle = fmListStyleOptionEnd WithWith .ListBox3.MultiSelect = fmMultiSelectMulti.ListStyle = fmListStyleOptionEnd WithEnd WithEnd Sub
模块代码
Sub GetData(control As IRibbonControl)UserForm1.ShowEnd Sub
今天代码有点冗余,小编偷懒,复制粘贴复制粘贴...也没注释,这是个坏习惯...过段时间回头看这段代码估计会稀里糊涂的,有兴趣的小伙伴可以封装个SQL的查询代码,在代码中调用,并且添加上注释...在发给小编
有细心的小伙伴可能会发现小编之前写Conn.Open的连接语句都是Data Source=" & ThisWorkbook.FullName,连接当前工作簿的表格,而今天的和之前有点不一样
其实跨工作簿查询只需要更改Conn.Open中的"DataSource="&Me.TextBox1.Text"
也就是所需要连接工作簿的指定路径
"Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties='Excel 12.0;HDR=yes;IMEX=0';Data Source=C:\Users\Administrator\Desktop\数据源.xlsx"
代码中直接指定了需要连接工作簿的完整名称,在SQL语句中使用常规的方法写即可完成跨工作博查询
但是,如果需要是连接当前工作簿,而查询别的工作簿的时候,在SQL语句中就需要更改下
Select 字段 From [Excel 12.0;DataBase=需要查询工作簿的完整路径].[需要查询的工作表$]
这些都是固定的用法,小伙伴稍微记住下即可,忘了可以翻下文章看看
Excel 12.0是目标工作簿的版本号
DataBase是指定查询工作簿的路径,第二个中括号是指定需要查询的工作表名称
...
示例文件下载
链接:https://pan.baidu.com/s/1lbEWThdUX_NN3tBP-l_EDg
提取码:abcd
收工!
如果小伙伴有好的思路,可以给小编留言
文章如果觉得有用,点个赞,小伙伴的每一次点赞和转发都是小编原创的动力
关注公众号↓




