Excel下拉公式,引用的路径和工作簿名称怎样根据单元格内容的变化而变化

某天有个朋友问到这样的问题,一个文件夹下有500多个文件,部分文件截图如图1,每个文件的格式一样,部分内容截图如图2,需要根据把这些文件的内容汇总在一张工作表。

图1

图2

需要汇总的工作表部分字段内容如图3:

图3

需要汇总的工作簿有500多个,字段有近100个,5万多个单元格内容来自500多个工作簿,用公式怎样引用那么多工作簿单元格内容,一个个工作簿引用,一个字段要写的公式就有500多个。当需要更改公式中单元格的引用,而不更改公式本身,可以用Indirect函数。我们先看看这个函数的语法。

Indirect(ref_text,[a1])

ref_text 为对单元格的引用,此单元格可以包含 A1-样式的引用、R1C1-样式的引用、定义为引用的名称或对文本字符串单元格的引用。如果 ref_text不是合法的单元格的引用,函数 INDIRECT 返回错误值#REF!或#NAME?。

如果 ref_text 是对另一个工作簿的引用(外部引用),则工作簿必须被打开。如果源工作簿没有打开,函数 INDIRECT 返回错误值#REF!。

a1 为一逻辑值,指明包含在单元格ref_text 中的引用的类型。

如果 a1 为 TRUE 或省略,ref_text被解释为 A1-样式的引用。

如果 a1 为 FALSE,ref_text被解释为 R1C1-样式的引用。

要引用500多个工作簿,必须这些工作簿全部打开,太麻烦了,因此,我们先把这500多个工作簿合并到一个工作簿的500多个工作表。操作步骤如下:

Step1、将需要合并的Excel工作簿放在一个文件夹中;

Step2、在该文件夹中新建一个工作簿;

Step3、打开新建立的Excel工作簿,按下【Alt+F11】组合键,在Visual Basic编辑器中选择“插入→模块”,在代码窗口输入以下代码,点击菜单栏运行,运行子过程/用户窗体,弹出需要合并的文件,关闭代码输入窗口。打开Excel工作簿,可以看到将选中的工作簿中的工作表都复制到了新建工作簿中。

Sub 合并汇总()

Application.DisplayAlerts = False

Application.ScreenUpdating = False

FileToOpen_N = Application.GetOpenFilename("xls文件,*.xls", _

p.s.如果是xlsx文件就修改文件类型为xlsx

Title:="请选择要合并工作簿", MultiSelect:=True)

Newbz = 0

On Error Resume Next

For Each FileToOpen In FileToOpen_N

If FileToOpen <> False Then

If Newbz = 0 Then

Booknum = Application.SheetsInNewWorkbook

Application.SheetsInNewWorkbook = 1

Workbooks.Add

Application.SheetsInNewWorkbook = Booknum

NewBookName = ActiveWorkbook.Name

Sheets(1).Name = "sheet_tmp"

Newbz = 1

End If

Set OpenBook = Workbooks.Open(FileToOpen)

For Each Xlsheet In OpenBook.Sheets

Xlsheet.CopyBefore:=Workbooks(NewBookName).Sheets("sheet_tmp")

Next

OpenBook.Close SaveChanges:=False

End If

Next

Workbooks(NewBookName).Sheets("sheet_tmp").Delete

Application.ScreenUpdating = True

Application.DisplayAlerts = True

Dim sht As Worksheet, lstRowZb As Integer, lstRow As Integer

'lstRowZb:总表的lastrow

Worksheets("1").Select

Worksheets("1").Range("a1:h1").CopyDestination:=Range("a1")

'复制表头

For Each sht In Worksheets

lstRowZb = Range("a1048576").End(xlUp).Row '每次COPY前取总表的最后一行

With sht

If .Name <> "1" Then

lstRow = .Range("a1048576").End(xlUp).Row

.Range("a2:h" & lstRow).CopyDestination:=Cells(lstRowZb + 1, "a")

End If

End With

Next sht

End Sub

此过程大概执行10分钟,执行完毕,500多个工作簿汇总到一个工作簿500多个工作表了,部分工作表截图如图4。

图4

接下来就是引用500多个工作表内容,先在汇总表里插入辅助列,辅助列为工作表名称,这里因为工作表名称左边的内容都相同,只是右边的数学不同,因此可以先输入第一个工作表名称,再拖动单元格右下角黑色+下拉。检测编号为500多个工作簿名称的前面编号,如图5,如果手工一个个输入要输入500多次,而且不能保证不输错。

图5

要遍历文件夹中的多个工作簿名称,可能很多人用VBA,这里介绍一个很简单很爽的方法,操作步骤如下:

Step1、鼠标左键点击,开始→运行→在对话框中输入字母“cmd”,进入dos模式 ,如图6:

图6

Step2、在dos模式输入命令行“cd c:\xueyuan”然后回车,再输入命令行“dir /b>rename.xls",可将文件夹中的文件名在rename.xls文件中列出,用Excel打开c:\xueyuan中的rename.xls,你会发现所有文件名称全部罗列在A列中。

Step3、在rename文件中的B1单元格输入A1单元格左边的检测编号,按快捷键【Ctrl+E】快速填充B列其他单元格内容。关于快速填充功能请点击文章查看,神奇的快速填充功能

图7

至此工作表名和检测编号全部录入完毕,接下来性别、年龄、采血编号等在如图2的表格上方的信息用indirect函数引用。C2单元格公式=INDIRECT("'"&$A2&"'!D3"),双击单元格右下角黑色+填充整列公式,往右拖动公式填充D列和E列公式。

图8

解释C2公式:如果不用indirect函数,直接引用工作表,C2公式为='P-检测报告单(1)'!D3,所以用indirect函数,要先用单引号和A列连接起来,再连接工作表名称后面的'!D3。

F列到最后一列字段多,要引用的内容都在每张表的表格部分,因此用vlookup函数匹配,F2公式=VLOOKUP(F$1,INDIRECT("'"&$A2&"'!$A$7:$D$55"),4,0),往右往下拖动公式填充全部单元格公式。

图9

总结:解决这个问题用到VBA多表合并、Dos命令提取文件夹下所有工作簿名称、快速填充、indriect函数引用不同工作表内容,以及vlookup函数查找。

(0)

相关推荐