如何使用EXCEL生成36进制序列号
今天接到一个朋友求助,需要生成一组数百个连续的数字+字母组合的序列号。要求:
1:序列号必须是按照0~9,A~Z的顺序排列;
2:序列号需要从一个指定的数值(WJG191B9)开始计数;
3:生成的数列要求不少于500个;
获得这个任务以后,我首先仔细分析了一下需求。这个需求的核心其实是要做一个10个数字加26个字母组合的36进制数列。而且不能随意生成,而是要从WJG191B9开始连续生成。
由于EXCEL本身并无36进制的相关函数,而我又懒得写程序,只想通过EXCEL的相关公式来做这个事情。所以一开始我设计了2个方法。
方法一:用大家熟悉的VLOOKUP()进行拼凑
思路是首先在EXCEL中的一个空白列上手动输入数字“0~9”和字母“A~Z”,然后使用VLOOKUP()函数进行一位一位的拼凑,最后再用字符合并函数CONCATENATE()将所有位按照顺序拼凑起来。
这样做,虽然逻辑上简单,但是需要将这8为36进制的数值转换成8组十进制数字然后再逐一进行VLOOKUP。如下图所示
用这种方法,难点是需要在表示10进制的8位数上(E到L列),使用IF()函数做一个进位识别。
具体进位识别思路是在第一列(L列)上用if语句写一个0~35的循环,如果上一行数字小于35,本行数字就等于35+1,否则等于0.
具体函数是:=IF(L3<35,L3+1,0)
然后,在后续的列上,识别前一位是否为0,如果等于0,本行就加一,否则等于上一行。
具体函数是:=IF(L4<>0,K3,K3+1)
这样做呢思路是很简单。使用的公式也就是3个,分别是Vlookup(),CONCATENATE()和IF()。
第二种思路是:使用字符集编码函数CHAR()来实现
在计算机中一共有255个字符集,在这个字符集中没有改字符都可以通过CHAR()函数来提取。
例如数字0~9的提取方式是:=CHAR(48)到=CHAR(57);
字母A~Z的提取方式是:=CHAR(65)到=CHAR(90);
使用这种方式,我们可以把0~9和A~Z的任何一个字符提取出来。但讨厌的是,这里数字和字母中间不是连续的
就用方法一种的思路分成8列,每一列从按照字符集提取函数CHAR()的规律提取对应的数值出来即可,然后在各位上识别本位上一行数值如果到Z,就恢复到=CHAR(48),如果到9就跳转到=CHAR(65)
具体函数是:=IF(X2=9,CHAR(65),IF(X2="Z",CHAR(48)))
另外在其他位上,再附加一个识别前一位是否为0,如果为0,本位CHAR数值+1.
和第一种方法的思路一样,8位全部算完以后,再用CONCATENATE()合并。
这样也可以把这个36为数值给瞅出来。
这里就不附图了。
虽然这两种方法都可以实现最终结果,但是都是用“凑数”的方法来做的,这抬不符合我的风格了,我要求的是完美。
那么有没有一种纯粹用数学方法直接求36进制数值的方法呢?答案当然是肯定的咯。既然EXCEL并没有36进制的函数,那么我就给excel做一个“10进制转36进制”的计算函数。
既然是做一个新函数,那么首先要打开EXCELL的VBA编辑器。具体方法是在打开一个空白EXCELL文档,然后:
1,按键ALT+F11
2,菜单选插入——模块,
这样就可以进入VBA编辑器,开始写代码了。
具体公式的设计思路:既然是10进制转36进制,那么关键就是计算每一位的余数,知道余数然后去提取0~9,A~Z对应的数值即可。
首先生成一个循环数列:v = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
然后用10进制数值除以36,循环取余,获得每一位的余数,再根据数列V进行循环查找,找到每一位对应的数值。
具体代码如下:
Function s(a As Long)
v = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Do
If a < 36 Then s = Mid(v, a + 1, 1) & s: Exit Do
m = a Mod 36
s = Mid(v, m + 1, 1) & s
If a = 36 Then s = 1 & s: Exit Do
a = (a - m) / 36
Loop
End Function
然后保存本EXCELL。在EXCELL的工作表中,写入=S(421605),得到的结果就是:91B9,这样以此类推下去就能吧这500个36进制数列全部生成出来了。