其实也没啥技巧,就是因为步骤多,显得复杂。
1. 自定义函数 fx,fy,fx将数据对齐转置成一列,fy 将多列数据合并成最终形式。
2. 变量 sht,获取除本页之外的所有工作表名称,ShName为筛选 sht 以“上数”开头的工作表。
3. 开始对每个工作表循环。变量 Rc,获取各工作表页内 A1:Z100区域;变量 Nr,对 Rc 区域各列分析其有数据的行数;变量 nLeft,对 Nr 的每列,计算后一列比前一列少一行,该列即为“款号”所在列序号;变量 sCol,将列序号转变为 列标。
4. 变量 Src,提取当前工作表“款号”所在列的第1-100行;变量 nType,“款号”所在行数;变量 nEnd,数据区域最末行行数;变量 sEnd,通过数据区域第一行,得到数据区最右侧列的序号。
5. 变量 sData,数据区全部数据;Sa,数据区第一行去掉左侧3列后的人员姓名标题;变量 Sb,提取工序;变量 Sc,提取工价;变量 Sd,提取款号;变量 Se,人员姓名所在的数据区。
6. 变量 Sf,利用自定义函数 fy,得到当前工作表的转置汇总。
7. 利用REDUCE函数堆叠各个工作表的结果,最后去掉 REDUCE函数产生的第一行空行,并按照第1列排序。
=LET(fx,LAMBDA(x,y,TOCOL(IF(y<>"",x,1/0),2,1)),fy,LAMBDA(XX,YY,ZZ,SS,Srd,IFNA(HSTACK(fx(XX,Srd),YY,fx(ZZ,Srd),fx(SS,Srd),fx(Srd,Srd)),YY)),sht,SHEETSNAME(,1,1),ShName,FILTER(sht,LEFT(sht,2)="上数"),sInfo,REDUCE("",ShName,LAMBDA(x,y,VSTACK(x,LET(Rc,INDIRECT("'"&y&"'!A1:Z100"),Nr,BYCOL(Rc,COUNTA),nLeft,MIN(MAP(SEQUENCE(25),LAMBDA(x,IF(INDEX(Nr,,x)=(INDEX(Nr,,x+1)+1),x,999)))),sCol,SUBSTITUTE(ADDRESS(1,nLeft,4),1,),Src,INDIRECT("'"&y&"'!"&sCol&"1:"&sCol&"100"),nType,XMATCH(1=1,Src<>"",,1),nEnd,LOOKUP("座",Src,ROW(1:100)),sEnd,SUM(N(INDIRECT("'"&y&"'!"&sCol&(1+nType)&":Z"&(1+nType))<>"")),sData,OFFSET(Src,nType,,nEnd-nType,sEnd),Sa,TAKE(TAKE(sData,,3-sEnd),1),Sb,DROP(TAKE(sData,,1),1),Sc,DROP(CHOOSECOLS(sData,2),1),Sd,OFFSET(Src,nType-1,,1,),Se,DROP(TAKE(sData,,3-sEnd),1),Sf,fy(Sa,Sd,Sb,Sc,Se),Sf)))),SORT(DROP(sInfo,1)))
|