今天我们来解决一道数据转置的题目,并以实例来探讨。
原数据图一效果如图二

需求将二维交叉表,转换成一维表
看到最终效果(图二)后,有三个问题需要解决
1.原数据表(图一)的姓名、班别需要重复4次,由原来的18行变成72行,如何解决?
2.科目名称如何重复18次后,自动变成下一个科目名称?
3.如何根据姓名和科目名称来匹配对应的成绩?
说到底,这个需求其实是对于原数据表数据的引用,不需要产生新的数据,可以使用INDIRECT
问题一解决
看到重复的数据,首先想到的办法是复制原数据A2:B19区域,然后复制粘贴4次。这样需要操作4次,如果一旦重复的次数增加,到达100次,那么这样就会花费大量的时间,这里来考虑能否使用引用函数来解决。
这里如果使用引用函数,就是如何在填充的时候,到达第18个学生的时候,再自动从第1个学生开始?
一共有18名学生,引用第一个学生,我们可以使用=原数据!A2;引用第二个学生,可以使用=原数据!A3,只是行号在变化,如何在第19个引用时候,再重第一个学生开始引用需要我们考虑。
这里就需要用到一个函数:MOD函数,这个函数是用来取余数的一个函数,比如=MOD(1,18),这个意思相当于1除以18余数是1。
根据这个函数来进行引用,第一个学生到第十七个学生都可以拿到对应的行数=INDIRECT("原数据!"&A&MOD(ROW(A1),18)+1)
但是在第十八个学生的时候,=MOD(ROW(A18),18)余数为0,没办法引用到第第十八个学生。这个时候我们从除数入手,除数减去1,公式就变成:
=INDIRECT("原数据!"&A&MOD(ROW(A1)-1,18)+2)
那么就可以解决引用到第十八个学生的问题,同时在A19时,第19个引用的时候,重新对于A2(第一个学生)进行引用。
作用到 班别 列只需要将A列改成B列即可,重新输入函数有没有直接拖拉填充就可以解决的办法呢?
这里就需要用到CHAR函数,这个是一个数字与符号匹配的函数,我们只需要记住A-Z匹配65-90,=CHAR(65),结果为A。
改良一下这个公式
原数据!"&CHAR(COLUMN(A1)+64)&MOD(ROW(A1)-1,18)+2)
需要下拉填充到哪里呢?
这里由于我们事先知道学生18个,重复4次,有72项,将向下选中72项后,按住Ctrl+D快速填充。
如图三

问题二解决
科目名称这里我们可以观察到在原数据的位置是D1=语文,E1=数学,F1=英语,G1=政治。
这里可以发现行数都一样,如何解决列数的问题,使得重复18次后自动引用到下一个成为我们需要考虑的事。
这里就需要了解另一个函数INT函数,这个函数是返回一个比参数小的最相邻的整数,例如=INT(2.2),结果就是2.
由于CHAR函数可以表示字母,D可以表示为=CHAR(68+0),E可以表示为=CHAR(68+1),
在第一次对18学生进行引用0,就可以保证拿到的全是语文科目;在新的一批引用时,保证全是1,就可以拿到数学科目。
那么我们得到字母列的取值函数=CHAR(68+INT((ROW(A1)-1)/18)),这样就可以保证前18次都是对于D的引用,第19次时对于E的引用。
最后综合公式为
原数据!"&CHAR(68+INT((ROW(A1)-1)/18))&1)
如图四

问题三解决
根据姓名和科目匹配到对应时间,由于在原数据里面这个是一个交叉形的数值,根据姓名所在行和科目所在列就可以拿到这个数值,这里我们使用INDEX函数,不了解的小伙伴可以看前一篇文章,。
使用INDEX函数之前,我们这里需要引入一个函数MATCH。
MATCH函数可以理解为返回项的相对位置,例如A1:A3包含数值5,15,25.那么=MATCH(5,A1:A3,0),返回值是1。第三个参数一般填0就行。
最后结合INDEX函数得到
原数原数据!$A$1:$A$19,0),MATCH(C2,原数据!$A$1:$G$1,0))
如图五
那么这样这个问题就解决了。
有其他想法,欢迎交流,如果需要本题练习素材,回复003。
