配色: 字号:
Excel VBA_BOM算法实例集锦
2017-12-20 | 阅:  转:  |  分享 
  
1,BOM算法之一

‘2013-5-28

‘http://club.excelhome.net/forum.php?mod=viewthread&tid=914702&page=1#pid6271907

PublicArr,d,d1,k,t

Sublqxs_0527()

''适用于加子件本身数量的算法

Dimi&,Brr,k2,t2,j&,aa,a

Setd=CreateObject("Scripting.Dictionary")

Setd1=CreateObject("Scripting.Dictionary")

Sheet5.Activate

[d:d]=""

Arr=[a1].CurrentRegion

ReDimBrr(1ToUBound(Arr),1To1)

Fori=2ToUBound(Arr)

d(Arr(i,1))=d(Arr(i,1))&i&","

Next

k=d.keys:t=d.items‘将层级及行数做成字典

Fori=0ToUBound(k)

Ifi=0Then

Callyy0(t(i),i)

Else

Callyy(t(i),i)

EndIf

Next

k2=d1.keys:t2=d1.items'':c1=i



Fori=UBound(k2)To1Step-1‘从最末级开始

t2(i)=Left(t2(i),Len(t2(i))-1)

IfInStr(t2(i),"|")Then

aa=Split(t2(i),"|")

Forj=0ToUBound(aa)

a=Split(aa(j),",")‘a(0)-本级行,a(2)-上级行

Brr(a(0),1)=Brr(a(0),1)+Arr(a(0),3)‘加子件本身数量

Brr(a(2),1)=Brr(a(2),1)+Brr(a(0),1)Arr(a(2),3)

Next

Else

a=Split(t2(i),",")

Brr(a(0),1)=Brr(a(0),1)+Arr(a(0),3)

Brr(a(2),1)=Brr(a(2),1)+Brr(a(0),1)Arr(a(2),3)

EndIf

Next

Range("d1:d"&UBound(Arr))=Brr

EndSub



Subyy(tt,c)

Dimk1,t1,t2,j&,aa,sj,gs,i&

t1=Left(t(c-1),Len(t(c-1))-1)‘上一级所在的行

t2=Left(tt,Len(tt)-1)‘本级所在的行

IfInStr(t2,",")Then

bb=Split(t2,",")

Forj=0ToUBound(bb)

IfInStr(t1,",")Then

aa=Split(t1,",")

Fori=UBound(aa)To0Step-1

IfVal(bb(j))>Val(aa(i))Then

sj=aa(i):gs=Arr(bb(j),3)‘sj-上级;gs-工时、需求量

d1(k(c))=d1(k(c))&bb(j)&","&gs&","&sj&"|"

‘把本级的行bb(j)、工时gs、上级行sj放入新的字典

ExitFor

EndIf

Next

Else

sj=t1:gs=Arr(bb(j),3)

d1(k(c))=d1(k(c))&bb(j)&","&gs&","&sj&"|"

EndIf

Next

Else

gs=Arr(t2,3):sj=t2-1

d1(k(c))=d1(k(c))&t2&","&gs&","&sj&"|"

EndIf

EndSub



Subyy0(tt,c)‘第1级时

Dimt1,bb,j&,sj,gs

t1=Left(tt,Len(tt)-1)

IfInStr(t1,",")Then

bb=Split(t1,",")

Forj=0ToUBound(bb)

sj=bb(j):gs=Arr(bb(j),3)

d1(k(c))=d1(k(c))&bb(j)&","&gs&","&sj&"|"

Next

Else

gs=Arr(t1,3):sj=t1

d1(k(c))=d1(k(c))&t1&","&gs&","&sj&"|"

EndIf

EndSub



2,BOM算法之二

‘2013-5-28

‘http://club.excelhome.net/thread-716135-1-1.html

Sublqxs_0528()

''适用于不加子件本身数量的算法

Dimi&,Brr,k2,t2,j&,aa,a

Setd=CreateObject("Scripting.Dictionary")

Setd1=CreateObject("Scripting.Dictionary")

Sheet5.Activate

[d:d]=""

Arr=[a1].CurrentRegion

ReDimBrr(1ToUBound(Arr),1To1)

Fori=2ToUBound(Arr)

d(Arr(i,1))=d(Arr(i,1))&i&","

Next

k=d.keys:t=d.items

Fori=0ToUBound(k)

Ifi=0Then

Callyy0(t(i),i)

Else

Callyy(t(i),i)

EndIf

Next

k2=d1.keys:t2=d1.items'':c1=i



Fori=UBound(k2)To1Step-1

t2(i)=Left(t2(i),Len(t2(i))-1)

IfInStr(t2(i),"|")Then

aa=Split(t2(i),"|")

Forj=0ToUBound(aa)

a=Split(aa(j),",")

IfBrr(a(0),1)=0ThenBrr(a(0),1)=Arr(a(0),3)

Brr(a(2),1)=Brr(a(2),1)+Brr(a(0),1)Arr(a(2),3)

Next

Else

a=Split(t2(i),",")

IfBrr(a(0),1)=0ThenBrr(a(0),1)=Arr(a(0),3)

Brr(a(2),1)=Brr(a(2),1)+Brr(a(0),1)Arr(a(2),3)

EndIf

Next

Range("d1:d"&UBound(Arr))=Brr

EndSub



3,BOM算法之三(成本计算)



Sublqxs_cb0528()

''适用于不加子件本身数量的成本算法

Dimi&,Brr,k2,t2,j&,aa,a,tt2,zjj

Setd=CreateObject("Scripting.Dictionary")

Setd1=CreateObject("Scripting.Dictionary")

''Sheet5.Activate

[i2:l50000]=""

Arr=[a1].CurrentRegion

ReDimBrr(1ToUBound(Arr),1To1)

Fori=2ToUBound(Arr)

d(Arr(i,1))=d(Arr(i,1))&i&","

Next

k=d.keys:t=d.items

Fori=0ToUBound(k)

Ifi=0Then

Callyy0(t(i),i)

Else

Callyy(t(i),i)

EndIf

Next

k2=d1.keys:t2=d1.items

''Forii=4ToUBound(Arr,2)

ii=4

Fori=UBound(k2)To1Step-1

tt2=Left(t2(i),Len(t2(i))-1)

IfInStr(tt2,"|")Then

aa=Split(tt2,"|")

Forj=0ToUBound(aa)

a=Split(aa(j),",")

IfBrr(a(0),ii-3)=0Then

zjj=Arr(a(0),3)Arr(a(0),ii)

Else

zjj=Brr(a(0),ii-3)

EndIf

Brr(a(2),ii-3)=Brr(a(2),ii-3)+zjjArr(a(2),3)

''IfCells(a(0),ii+5)=0Then

''zjj=Arr(a(0),3)Arr(a(0),ii)

''Else

''zjj=Cells(a(0),ii+5)

''EndIf

''Cells(a(2),ii+5)=Cells(a(2),ii+5)+zjjArr(a(2),3)

Next

Else

a=Split(t2(i),",")

IfBrr(a(0),ii-3)=0ThenBrr(a(0),ii-3)=Arr(a(0),3)Arr(a(0),ii)

Brr(a(2),ii-3)=Brr(a(2),ii-3)+Brr(a(0),ii-3)Arr(a(2),3)

EndIf

Next

Brr(1,ii-3)=Cells(1,ii+5).Value

Range(Cells(1,ii+5),Cells(UBound(Arr),ii+5))=Application.Index(Brr,0,ii-3)'':EraseBrr

''Range(Cells(1,ii+5),Cells(UBound(Arr),ii+5))=Brr:EraseBrr

''Next

EndSub

4,BOM算法之四(工时计算)



Sublqxs_gs0528()

''适用于加子件本身数量的工时算法

Dimi&,Brr,k2,t2,j&,aa,a,tt2,zjj

Setd=CreateObject("Scripting.Dictionary")

Setd1=CreateObject("Scripting.Dictionary")

''Sheet5.Activate

[j2:l50000]=""

Arr=[a1].CurrentRegion

ReDimBrr(1ToUBound(Arr),1ToUBound(Arr,2)-3)

Fori=2ToUBound(Arr)

d(Arr(i,1))=d(Arr(i,1))&i&","

Next

k=d.keys:t=d.items

Fori=0ToUBound(k)

Ifi=0Then

Callyy0(t(i),i)

Else

Callyy(t(i),i)

EndIf

Next

k2=d1.keys:t2=d1.items

Forii=5ToUBound(Arr,2)

Fori=UBound(k2)To1Step-1

tt2=Left(t2(i),Len(t2(i))-1)

IfInStr(tt2,"|")Then

aa=Split(tt2,"|")

Forj=0ToUBound(aa)

a=Split(aa(j),",")

IfArr(a(0),ii)<>0Then

zjj=Arr(a(0),3)Arr(a(0),ii)

Brr(a(0),ii-3)=Brr(a(0),ii-3)+zjj

Brr(a(2),ii-3)=Brr(a(2),ii-3)+Arr(a(2),3)Brr(a(0),ii-3)

Else

Brr(a(2),ii-3)=Brr(a(2),ii-3)+Arr(a(2),3)Brr(a(0),ii-3)EndIf

Next

Else

a=Split(tt2,",")

IfBrr(a(0),ii-3)=0ThenBrr(a(0),ii-3)=Arr(a(0),3)Arr(a(0),ii)

Brr(a(2),ii-3)=Brr(a(2),ii-3)+Brr(a(0),ii-3)Arr(a(2),3)

EndIf

Next

Brr(1,ii-3)=Cells(1,ii+5).Value

Range(Cells(1,ii+5),Cells(UBound(Arr),ii+5))=Application.Index(Brr,0,ii-3)Next

EndSub



5,BOM算法之五(成本工时计算)



Sublqxs_cbgs0528()

''适用于加子件本身数量的工时算法

''适用于不加子件本身数量的成本算法

Dimi&,Brr,k2,t2,j&,aa,a,tt2,zjj

Setd=CreateObject("Scripting.Dictionary")

Setd1=CreateObject("Scripting.Dictionary")

''Sheet5.Activate

[i2:l50000]=""

Arr=[a1].CurrentRegion

ReDimBrr(1ToUBound(Arr),1ToUBound(Arr,2)-3)

Fori=2ToUBound(Arr)

d(Arr(i,1))=d(Arr(i,1))&i&","

Next

k=d.keys:t=d.items

Fori=0ToUBound(k)

Ifi=0Then

Callyy0(t(i),i)

Else

Callyy(t(i),i)

EndIf

Next

k2=d1.keys:t2=d1.items

Forii=4ToUBound(Arr,2)

Fori=UBound(k2)To1Step-1

tt2=Left(t2(i),Len(t2(i))-1)

IfInStr(tt2,"|")Then

aa=Split(tt2,"|")

Forj=0ToUBound(aa)

a=Split(aa(j),",")

Ifii<>4Then

IfArr(a(0),ii)<>0Then

zjj=Arr(a(0),3)Arr(a(0),ii)

Brr(a(0),ii-3)=Brr(a(0),ii-3)+zjj

Brr(a(2),ii-3)=Brr(a(2),ii-3)+Arr(a(2),3)Brr(a(0),ii-3)

Else

Brr(a(2),ii-3)=Brr(a(2),ii-3)+Arr(a(2),3)Brr(a(0),ii-3)

EndIf

Else

IfBrr(a(0),ii-3)=0Then

zjj=Arr(a(0),3)Arr(a(0),ii)

Else

zjj=Brr(a(0),ii-3)

EndIf

Brr(a(2),ii-3)=Brr(a(2),ii-3)+zjjArr(a(2),3)

EndIf

Next

EndIf

Next

Brr(1,ii-3)=Cells(1,ii+5).Value

Next

Cells(1,UBound(Arr,2)+2).Resize(UBound(Arr),UBound(Arr,2)-3)=Brr

EndSub



当看到BOM表格的时候,我们大都会觉得眼花缭乱,被那么多的层级搞糊涂了,我不知道他们在实际工作中是怎么计算的,如果手工计算的话,真是需要足够的耐心和毅力。

最近看到有会员来求助,经过一段时间的研究,我找到了一个计算方法,称之为蓝桥方法。希望能够使被这种计算困扰的人们解放出来。

该方法的思路比较简单清晰:

先用字典求得各层级材料所在行的行数;这是容易做到的;

通过下一层级与上一层级的逐级比较,获得各层级材料的上一层级所在的行位置,并且放入另一个字典;

通过不同的计算方法计算成本和工时的汇总。



6,BOM算法之电梯成本计算

‘2013-5-29

‘http://club.excelhome.net/forum.php?mod=viewthread&tid=1019742&page=2#pid6954544

PublicArr,d,d1,k,t

Sublqxs_ff()

''适用于加子件本身数量的算法

Dimi&,Brr,k2,t2,j&,aa,a

Setd=CreateObject("Scripting.Dictionary")

Setd1=CreateObject("Scripting.Dictionary")

[g2:g5000]=""

Arr=[a1].CurrentRegion

ReDimBrr(1ToUBound(Arr),1To1)

Fori=2ToUBound(Arr)

d(Arr(i,1))=d(Arr(i,1))&i&","

Next

k=d.keys:t=d.items

Fori=0ToUBound(k)

Ifi=0Then

Callyy0(t(i),i)

Else

Callyy(t(i),i)

EndIf

Next

k2=d1.keys:t2=d1.items



Fori=UBound(k2)To1Step-1

t2(i)=Left(t2(i),Len(t2(i))-1)

IfInStr(t2(i),"|")Then

aa=Split(t2(i),"|")

Forj=0ToUBound(aa)

a=Split(aa(j),",")

Brr(a(0),1)=Brr(a(0),1)+Arr(a(0),6)Arr(a(0),5)

Brr(a(2),1)=Brr(a(2),1)+Brr(a(0),1)Arr(a(2),5)

Next

Else

a=Split(t2(i),",")

Brr(a(0),1)=Brr(a(0),1)+Arr(a(0),6)Arr(a(0),5)

Brr(a(2),1)=Brr(a(2),1)+Brr(a(0),1)Arr(a(2),5)

EndIf

Next

t2(0)=Left(t2(0),Len(t2(0))-1)‘对父级单行的判断

IfInStr(t2(0),"|")Then

aa=Split(t2(0),"|")

Forj=1ToUBound(aa)

a=Split(aa(j),",")

IfVal(a(0))-Val(a(3))=0Then

Brr(a(0),1)=Arr(a(0),6)Arr(a(0),5)

EndIf

Next

EndIf

Brr(1,1)=[g1].Value

Range("g1:g"&UBound(Arr))=Brr

EndSub



PublicSubyy(tt,c)

''by:蓝桥玄霜2013-5-28

Dimk1,t1,t2,j&,aa,sj,gs,i&,bb

t1=Left(t(c-1),Len(t(c-1))-1)

t2=Left(tt,Len(tt)-1)

IfInStr(t2,",")Then

bb=Split(t2,",")

Forj=0ToUBound(bb)

IfInStr(t1,",")Then

aa=Split(t1,",")

Fori=UBound(aa)To0Step-1

IfVal(bb(j))>Val(aa(i))Then

sj=aa(i):gs=Arr(bb(j),5)

''Ifj<>UBound(bb)Then‘对父级以外的层级判断其结束行,但是会有些行不准确,虽然不影响成本工时的计算结果

''js=bb(j+1)-1

''Else

''Ifi<>UBound(aa)Thenjs=aa(i+1)-1Elsejs=UBound(Arr)

''EndIf

''d1(k(c))=d1(k(c))&bb(j)&","&gs&","&sj&","&js&"|"

d1(k(c))=d1(k(c))&bb(j)&","&gs&","&sj&"|"

ExitFor

EndIf

Next

Else

sj=t1:gs=Arr(bb(j),5)

''Ifj<>UBound(bb)Then

''js=bb(j+1)-1

''Else

''Ifi<>UBound(aa)Thenjs=aa(i+1)-1Elsejs=UBound(Arr)

''EndIf

''d1(k(c))=d1(k(c))&bb(j)&","&gs&","&sj&","&js&"|"

d1(k(c))=d1(k(c))&bb(j)&","&gs&","&sj&"|"

EndIf

Next

Else

gs=Arr(t2,5):sj=t2-1

d1(k(c))=d1(k(c))&t2&","&gs&","&sj&"|"

EndIf

EndSub



PublicSubyy0(tt,c)

''by:蓝桥玄霜2013-5-28

Dimt1,bb,j&,sj,gs

t1=Left(tt,Len(tt)-1)

IfInStr(t1,",")Then

bb=Split(t1,",")

Forj=0ToUBound(bb)

sj=bb(j):gs=Arr(bb(j),5)

Ifj<>UBound(bb)Then‘增加结束行判断

js=bb(j+1)-1

Else

js=UBound(Arr)

EndIf

d1(k(c))=d1(k(c))&bb(j)&","&gs&","&sj&","&js&"|"

Next

Else

gs=Arr(t1,5):sj=t1

d1(k(c))=d1(k(c))&t1&","&gs&","&sj&","&t1&"|"

EndIf

EndSub



7,根据缩进量判断父项所包含子项的数量

‘2013-6-26

‘http://club.excelhome.net/thread-1030264-1-1.html

Sublqxs()

Dimi&,Arr,d,d1,k,t,x$,j&,a$,b$,n&

Dimt1,t2,aa,c%,bb

Setd=CreateObject("Scripting.Dictionary")

Sheet1.Activate

[b2:b5000].ClearContents

Arr=[a1].CurrentRegion

Fori=2ToUBound(Arr)

n=Cells(i,1).IndentLevel

d(n)=d(n)&i&","

Next

k=d.keys:t=d.items

Forc=UBound(k)To1Step-1

t1=Left(t(c-1),Len(t(c-1))-1)

t2=Left(t(c),Len(t(c))-1)

IfInStr(t2,",")Then

bb=Split(t2,",")

Forj=UBound(bb)To0Step-1

IfInStr(t1,",")Then

aa=Split(t1,",")

Fori=UBound(aa)To0Step-1

IfVal(bb(j))>Val(aa(i))Then

Cells(aa(i),2)=Cells(aa(i),2)+1

Cells(bb(j),2)=Cells(bb(j),2)+0

ExitFor

EndIf

Next

Else

Cells(t1,2)=Cells(t1,2)+1

Cells(bb(j),2)=Cells(bb(j),2)+0

EndIf

Next

Else

IfInStr(t1,",")Then

aa=Split(t1,",")

Fori=UBound(aa)To0Step-1

IfVal(t2)>Val(aa(i))Then

Cells(aa(i),2)=Cells(aa(i),2)+1

Cells(t2,2)=Cells(t2,2)+0

ExitFor

EndIf

Next

Else

Cells(t1,2)=Cells(t1,2)+1

Cells(t2,2)=Cells(t2,2)+0

EndIf

EndIf

Next

EndSub



Subtest()

‘by:yangyangzhifeng用两个数组

Dimi&,ar(0To10),br&(0To10),r&,n&

n=Cells(Rows.Count,1).End(3).Row

Fori=2Ton

r=Cells(i,1).IndentLevel

Ifr>0Thenar(r-1)=ar(r-1)+1

Ifbr(r)>0Then

Cells(br(r),2)=ar(r)

EndIf

ar(r)=0

br(r)=i

Next

Fori=0To10

Ifbr(i)>0Then

Cells(br(i),2)=ar(i)

EndIf

Next

EndSub



8,BOM算法之六(清单数量计算)

‘2013-7-4

‘http://www.excelpx.com/thread-304244-1-1.html

PublicArr,d,d1,k,t

Sublqxs_cbgs()

''by:蓝桥玄霜



Dimi&,Brr,k2,t2,j&,aa,a,tt2,zjj

Setd=CreateObject("Scripting.Dictionary")

Setd1=CreateObject("Scripting.Dictionary")

[e2:e50000]=""

Arr=[a1].CurrentRegion

Fori=2ToUBound(Arr)

d(Arr(i,4))=d(Arr(i,4))&i&","

Next

k=d.keys:t=d.items

Fori=0ToUBound(k)

Ifi=0Then

Callyy0(t(i),i)‘本行+本级数量+上级行

Else

Callyy(t(i),i)

EndIf

Next

k2=d1.keys:t2=d1.items

Fori=0ToUBound(k2)

tt2=Left(t2(i),Len(t2(i))-1)

IfInStr(tt2,"|")Then

aa=Split(tt2,"|")

Forj=0ToUBound(aa)

a=Split(aa(j),",")

sjsl=Cells(a(2),5)''上级数量

Cells(a(0),5)=Cells(a(0),5)+sjslArr(a(0),2)

Next

Else

a=Split(tt2,",")

Ifi=0Then

Cells(a(0),5)=Arr(a(0),2)

Else

sjsl=Cells(a(2),5)''上级数量

Cells(a(0),5)=Cells(a(0),5)+sjslArr(a(0),2)

EndIf

EndIf

Next

EndSub

9,计算层级

‘2017-11-3

‘http://club.excelhome.net/forum.php?mod=viewthread&tid=1377229&pid=9289870&page=1&extra=#pid9289870



Sublqxs()

DimArr,d,d1,k,t,n

Dimi&,j&,aa,sj$,x&

Dimk1,t1,bb,tt1,tt2



Setd=CreateObject("Scripting.Dictionary")

Setd1=CreateObject("Scripting.Dictionary")

[f2:g50000].ClearContents



Arr=Range("a1").CurrentRegion

sj=Arr(2,3)

Fori=2ToUBound(Arr)

n=Arr(i,2)

d(n)=d(n)&i&","

d1(n)=d1(n)&Arr(i,3)&","

Next

k=d.keys:t=d.items

k1=d1.keys:t1=d1.items

Fori=1ToUBound(k)

tt2=Left(t(i),Len(t(i))-1)''本级所在的行

IfInStr(tt2,",")Then

bb=Split(tt2,",")

Forj=0ToUBound(bb)

tt1=Left(t(i-1),Len(t(i-1))-1)''上一级所在的行

IfInStr(tt1,",")Then

aa=Split(tt1,",")

Forx=UBound(aa)To0Step-1

IfVal(bb(j))>Val(aa(x))Then

sj=Cells(aa(x),3).Value''sj-上级;

Cells(bb(j),6)=sj:ExitFor

EndIf

Next

Else

IfVal(bb(j))>Val(tt1)Then

sj=Cells(tt1,3).Value''sj-上级;

Cells(bb(j),6)=sj

EndIf

EndIf

Next

EndIf

Next

EndSub



‘2013-7-7

‘http://club.excelhome.net/thread-1032524-1-1.html

Sublqxs()

DimArr,i&,gxm$

Dimd,k,t

Setd=CreateObject("Scripting.Dictionary")

Sheet1.Activate

[d2:f500].ClearContents

Arr=[a1].CurrentRegion

[c2].Resize(UBound(Arr)-1,1).Copy[d2]

gxm=Arr(2,1):n=1:d(gxm)=1

Fori=3ToUBound(Arr)

Ifd.exists(Arr(i,2))Then

d(Arr(i,1))=d(Arr(i,2))+1

Cells(i,4)=Space((d(Arr(i,1))-1)2)&Cells(i,4)

EndIf

Next

k=d.keys:t=d.items

[e2].Resize(d.Count)=Application.Transpose(t)

[f2].Formula="=if(countif(b:b,A:A)=0,""是"","""")"

[f2].AutoFill[f2].Resize(d.Count)

EndSub

10,超级排序

‘2013-7-10

‘http://club.excelhome.net/thread-1033292-1-1.html

PublicArr,d,d1,k,t,d2

Sublqxs_超级排序()

Dimi&,Brr,k2,t2,j&,aa,a,y&,x&,col%

Dimn&,m&,zj,sj

Setd=CreateObject("Scripting.Dictionary")

Setd1=CreateObject("Scripting.Dictionary")

Setd2=CreateObject("Scripting.Dictionary")

Sheet2.Activate

[g:p]=""

Arr=[a8].CurrentRegion

Arr=[a1].Resize(UBound(Arr)+7,UBound(Arr,2))

Fori=9ToUBound(Arr)

d(Arr(i,2))=d(Arr(i,2))&i&","

Next

k=d.keys:t=d.items''将层级及行数做成字典

Fori=0ToUBound(k)

Ifi=0Then

Callyy0(t(i),i)

Else

Callyy(t(i),i)

EndIf

Next

k2=d1.keys:t2=d1.items'':各层级的本行+父子级行数+序号+上级行的字典



Fori=UBound(k2)To0Step-1''从最末级开始

Brr=Arr

[m:p]=""

t2(i)=Left(t2(i),Len(t2(i))-1):n=0

IfInStr(t2(i),"|")Then

aa=Split(t2(i),"|")

Forj=0ToUBound(aa)

n=n+1

a=Split(aa(j),",")''a(0)-本级行,a(3)-上级行

Ifn=1Then

Cells(n,13).Resize(1,UBound(a)+1)=a:

Cells(n,15)=(Cells(n,15).Value)1

sj=a(3)

Else

Ifa(3)=sjOri=0Then

Cells(n,13).Resize(1,UBound(a)+1)=a

Cells(n,15)=(Cells(n,15).Value)1

Else

[m1].Resize(n-1,4).SortCells(1,15)

crr=[m1].Resize(n-1,4)

m=crr(1,4)

Fory=1ToUBound(crr)

zj=Val(crr(y,2))''行数

Forx=1Tozj

m=m+1

Forcol=1To5

Brr(m,col)=Arr(crr(y,1)+x-1,col)

Next

Next

Next

n=1

[m:p]=""

Cells(n,13).Resize(1,UBound(a)+1)=a

Cells(n,15)=(Cells(n,15).Value)1

sj=a(3)

EndIf

Ifj=UBound(aa)Then

[m1].Resize(n,4).SortCells(1,15)

crr=[m1].Resize(n,4)

Ifi=0Thenm=8Elsem=crr(1,4)

Fory=1ToUBound(crr)

zj=Val(crr(y,2))

Forx=1Tozj

m=m+1

Forcol=1To5

Brr(m,col)=Arr(crr(y,1)+x-1,col)

Next

Next

Next

[m:p]=""

EndIf

EndIf

Next

EndIf

Arr=Brr

Next

Range("g1").Resize(UBound(Arr),5)=Arr

EndSub



Subyy(tt,c)

Dimk1,t1,t2,j&,aa,sj,gs,i&

t1=Left(t(c-1),Len(t(c-1))-1)''上一级所在的行

t2=Left(tt,Len(tt)-1)''本级所在的

IfInStr(t2,",")Then

bb=Split(t2,",")

Forj=0ToUBound(bb)

IfInStr(t1,",")Then

aa=Split(t1,",")

Fori=UBound(aa)To0Step-1

IfVal(bb(j))>Val(aa(i))Then

n=0:sj=aa(i):gs=Arr(bb(j),3)''sj-上行级;gs-序号

IfVal(bb(j))
Do

n=n+1

IfArr(bb(j)+n,2)<=c+1Then

ks=bb(j):js=ks+n-1

GoTo100

Else

EndIf

LoopWhileArr(bb(j)+n,2)>c+1Andbb(j)+n
ks=bb(j):js=ks+n:

Else

ks=bb(j):js=ks

EndIf

100:

hs=js-ks+1''父级+子级的行数

d1(k(c))=d1(k(c))&bb(j)&","&hs&","&gs&","&sj&"|"''bb(j)-本行级

ExitFor

EndIf

Next

Else

sj=t1:gs=Arr(bb(j),3):n=0

Do

n=n+1

IfArr(bb(j)+n,2)<=c+1Then

ks=bb(j):js=ks+n-1

GoTo200

Else

EndIf

LoopWhileArr(bb(j)+n,2)>c+1Andbb(j)+n
ks=bb(j):js=ks+n:

200:

hs=js-ks+1''父级+子级的行数

d1(k(c))=d1(k(c))&bb(j)&","&hs&","&gs&","&sj&"|"''bb(j)-本行级

EndIf

Next

Else

gs=Arr(t2,3):sj=t2-1

js=UBound(Arr)

ks=t2:hs=js-ks+1

d1(k(c))=d1(k(c))&t2&","&hs&","&gs&","&sj&"|"

EndIf

EndSub



Subyy0(tt,c)''第1级时

Dimt1,bb,j&,sj,gs,ks,js,hs

t1=Left(tt,Len(tt)-1)

IfInStr(t1,",")Then

bb=Split(t1,",")

Forj=0ToUBound(bb)

sj=bb(j):gs=Arr(bb(j),3)

Ifj=UBound(bb)Then

js=UBound(Arr)

Else

js=bb(j+1)-1

EndIf

d2(k(c))=d2(k(c))&js&","

ks=bb(j):hs=js-ks+1

d1(k(c))=d1(k(c))&bb(j)&","&hs&","&gs&","&sj&"|"''本级行,包含子件的行数,本级序号,上级行

Next

Else

gs=Arr(t1,3):sj=t1

js=UBound(Arr)

ks=t1:hs=js-ks+1

d1(k(c))=d1(k(c))&t1&","&hs&","&gs&","&sj&"|"

EndIf

EndSub



11,Bom表按结构排序by:thtfzhaobo

‘2013-8-1

‘http://club.excelhome.net/thread-1041551-2-1.html

DimxlappAsExcel.Application

Dimdic_bom,dic_list,old_array,new_array(),new_r



SubBom表按结构排序()

Dimlastrow,sheet_name

Dimbom_母件编码

Setxlapp=Application

OnErrorResumeNext

xlapp.ScreenUpdating=False

''读取原值

Withxlapp.ActiveSheet

sheet_name=.Name

bom_母件编码=.Cells(2,2)

lastrow=.Range("b65535").End(xlUp).Row

old_array=.Range(.Cells(5,1),.Cells(lastrow,6)).Value

EndWith



''排序

CallBom排序(bom_母件编码,2,3,old_array)



''输出

IfUBound(new_array)>0Then

Withxlapp.Sheets.Add

xlapp.Sheets(sheet_name).Rows("1:4").CopyDestination:=.Cells(1,1)

.Cells(5,1).Resize(UBound(new_array),UBound(new_array,2))=new_array

.Cells.EntireColumn.AutoFit

EndWith

EndIf

xlapp.ScreenUpdating=True

EndSub



FunctionBom排序(bom_母件编码,母列,子列,old_array)

Dimi,lastrow,arr

OnErrorResumeNext

''准备字典

Setdic_bom=CreateObject("Scripting.Dictionary")

Setdic_list=CreateObject("Scripting.Dictionary")

Fori=1ToUBound(old_array)

dic_list(old_array(i,母列)&"|"&old_array(i,子列))=i

Ifdic_bom.exists(old_array(i,母列))Then

dic_bom(old_array(i,母列))(old_array(i,子列))=""

Else

Setdic_bom(old_array(i,母列))=CreateObject("Scripting.Dictionary")

dic_bom(old_array(i,母列))(old_array(i,子列))=""

EndIf

Nexti

''排序

ReDimnew_array(1ToUBound(old_array),1ToUBound(old_array,2))

Ifbom_母件编码=""Thenbom_母件编码=old_array(1,母列)

Ifdic_bom.exists(bom_母件编码)Then

arr=dic_bom(bom_母件编码).Keys

Call嵌套排序(bom_母件编码,arr,old_array,new_array(),0,dic_bom,dic_list)

EndIf

EndFunction



Function嵌套排序(母件,子件,old_array,new_array(),new_r,dic_bom,dic_list)

Dimi,j,brr

''IfUBound(子件)>0ThenCallQuickSort(子件,LBound(子件),UBound(子件))

Fori=0ToUBound(子件)

new_r=new_r+1''新的排位序号

Forj=1ToUBound(old_array,2)''一行数据赋给新数组

new_array(new_r,j)=old_array(dic_list(母件&"|"&子件(i)),j)

Nextj

Ifdic_bom.exists(子件(i))Then

brr=dic_bom(子件(i)).Keys

Call嵌套排序(子件(i),brr,old_array,new_array,new_r,dic_bom,dic_list)

EndIf

Nexti

EndFunction







12,计算层级汇总

‘http://club.excelhome.net/forum.php?mod=viewthread&tid=1131680&page=1#pid7707426

‘2014-6-22

PublicArr,d,d1,k,t

Sublqxs_0622()

Dimi&,Brr,k2,t2,j&,aa,a

Setd=CreateObject("Scripting.Dictionary")

Setd1=CreateObject("Scripting.Dictionary")

Sheet2.Activate

Arr=[a1].CurrentRegion

ReDimBrr(1ToUBound(Arr),1To1)

Brr(1,1)=Arr(1,4)

Fori=2ToUBound(Arr)

d(Len(Arr(i,1)))=d(Len(Arr(i,1)))&i&","

IfArr(i,12)="否"ThenCells(i,4)=""

Next

k=d.keys:t=d.items

Fori=UBound(k)To0Step-1

Ifi=0Then

Callyy0(t(i),i)

Else

Callyy(t(i),i)

EndIf

Next

k2=d1.keys:t2=d1.items



Fori=0ToUBound(k2)-1

t2(i)=Left(t2(i),Len(t2(i))-1)

IfInStr(t2(i),"|")Then

aa=Split(t2(i),"|")

Forj=0ToUBound(aa)

a=Split(aa(j),",")''a(0)-本级行,a(2)-上级行

Brr(a(0),1)=Brr(a(0),1)+Arr(a(0),4)

Brr(a(2),1)=Brr(a(2),1)+Arr(a(0),4)

Next

Else

a=Split(t2(i),",")

Brr(a(2),1)=Brr(a(2),1)+Brr(a(0),1)

EndIf

Next

Range("d1:d"&UBound(Arr))=Brr

ActiveWindow.DisplayZeros=False

EndSub



Subyy(tt,c)

Dimk1,t1,t2,j&,aa,sj,gs,i&

t1=Left(t(c-1),Len(t(c-1))-1)''上一级所在的行

t2=Left(tt,Len(tt)-1)''本级所在的行

IfInStr(t2,",")Then

bb=Split(t2,",")

Forj=0ToUBound(bb)

IfInStr(t1,",")Then

aa=Split(t1,",")

Fori=UBound(aa)To0Step-1

IfVal(bb(j))>Val(aa(i))Then

sj=aa(i):gs=Arr(bb(j),4)

d1(k(c))=d1(k(c))&bb(j)&","&gs&","&sj&"|"

ExitFor

EndIf

Next

Else

sj=t1:gs=Arr(bb(j),4)

d1(k(c))=d1(k(c))&bb(j)&","&gs&","&sj&"|"

EndIf

Next

Else

gs=Arr(t2,4):sj=t2-1

d1(k(c))=d1(k(c))&t2&","&gs&","&sj&"|"

EndIf

EndSub



Subyy0(tt,c)''第1级时

Dimt1,bb,j&,sj,gs

t1=Left(tt,Len(tt)-1)

IfInStr(t1,",")Then

bb=Split(t1,",")

Forj=0ToUBound(bb)

sj=bb(j):gs=Arr(bb(j),4)

d1(k(c))=d1(k(c))&bb(j)&","&gs&","&sj&"|"

Next

Else

gs=Arr(t1,4):sj=t1

d1(k(c))=d1(k(c))&t1&","&gs&","&sj&"|"

EndIf

EndSub



‘by:sz_wap

Subsz_wap()

r=[a65536].End(3).Row''结束行

Arr=Range(Cells(1,"A"),Cells(r,"L"))''区域

Setdic=CreateObject("scripting.dictionary")



Fori=2Tor

IfArr(i,12)="否"Then

dic(Arr(i,1))=Array(0,0,0,0,0)

Else

ForEachdIndic

IfArr(i,1)Liked&""Then

Brr=dic(d)

Forj=4To8

Brr(j-4)=Brr(j-4)+Arr(i,j)

Next

dic(d)=Brr

EndIf

Next

EndIf

Next



Fori=2Tor

IfArr(i,12)="否"ThenCells(i,"d").Resize(1,5)=dic(Arr(i,1))

Next

EndSub

13,自动分级显示by:lee1892

‘http://club.excelhome.net/forum.php?mod=viewthread&tid=1131789&page=1#pid7711993

SubMacro1()

DimaData,i&

WithActiveSheet

.Cells.ClearOutline

With.Outline

.AutomaticStyles=False

.SummaryRow=xlAbove

.SummaryColumn=xlRight

EndWith

aData=.Range("A1").CurrentRegion

Fori=2ToUBound(aData)

.Rows(i).OutlineLevel=aData(i,2)

Next

EndWith

EndSub

14,自动分级(字典套字典,递归)

‘2014-11-2

‘http://club.excelhome.net/thread-1162643-2-1.html

DimArr,d1,t1

Sublqxs1()

Dimd,k,t,i&,ii&,x,y,m,n&,col%,c%

Setd=CreateObject("Scripting.Dictionary")

Setd1=CreateObject("Scripting.Dictionary")

Sheet1.Activate

[d:bz].ClearContents

Arr=[a1].CurrentRegion

Fori=2ToUBound(Arr)

Setr1=[b:b].Find(Arr(i,1),,,1)

Ifr1IsNothingThen

x=Arr(i,1):y=Arr(i,2)

Ifd.exists(x)=FalseThenSetd(x)=CreateObject("Scripting.Dictionary")

d(x)(y)=i

EndIf

x=Arr(i,1):y=Arr(i,2)

Ifd1.exists(x)=FalseThenSetd1(x)=CreateObject("Scripting.Dictionary")

d1(x)(y)=i

Next

k=d.keys:t=d.items

k1=d.keys:t1=d.items:n=1:col=3

Fori=0ToUBound(k)

n=n+1:c=col+1

Cells(n,c)=k(i)

kk=t(i).keys:tt=t(i).items:c=c+1

Forii=0ToUBound(kk)

n=n+1

Cells(n,c)=Arr(tt(ii),2)

m=tt(ii)

Callyyy(m,n,c)

Next

Next

EndSub



Subyyy(m,n,c)

Do

Ifd1.exists(Arr(m,2))Then

kk1=t1(i).keys:tt1=t1(i).items:c=c+1

Forjj=0ToUBound(kk1)

n=n+1

Cells(n,c)=Arr(tt1(jj),2)

m=tt1(jj)

Callyyy(m,n,c)

Next

Else

ExitDo

EndIf

Loop

EndSub

15,层级显示

‘2016-12-2

‘http://club.excelhome.net/thread-1315401-1-1.html

SubProcessTree()

DimrParentsAsRange,rNodeAsRange,rOutAsRange

DimlRowAsLong,Arr

Setdic=CreateObject("Scripting.Dictionary")

SetrParents=Range("A2",Range("A2").End(xlDown))''registallparents

SetrOut=Range("G2")''startpnt

[f2:i5000].ClearContents

[f2:i5000].Borders.LineStyle=xlNone

Arr=[a1].CurrentRegion

Fori=2ToUBound(Arr)

Ifdic.exists(Arr(i,1))=FalseThenSetdic(Arr(i,1))=CreateObject("Scripting.Dictionary")

dic(Arr(i,1))(Arr(i,2))=Arr(i,3)

Next

CallDisplayBOM("Transformer",dic,rOut,lRow,0)''rootNode"Transformer"

[f1].CurrentRegion.Borders.LineStyle=1

Setdic=Nothing

EndSub



‘另一种写法:

ForEachrNodeInrParents''enumNode

IfNotdic.exists(rNode.Value)Thendic.AddrNode.Value,NewCollection''dic.addV1,NewCollection

dic(rNode.Value).Add(rNode.Offset(,1).Value)

NextrNode



SubDisplayBOM(ByValsParentAsString,dicAsVariant,rOutAsRange,ByReflRowAsLong,ByVallLevelAsLong)''dicAsVariant(insteadofdic)

DimvChild

IflLevel+lRow=0ThenrOut=sParent

ForEachvChildIndic(sParent)

lRow=lRow+1

rOut(lRow,0)=lLevel+1''层级

rOut(lRow,1)=vChild''子阶

rOut(lRow,2)=dic(sParent)(vChild)''数量

Ifdic.exists(vChild)ThenCallDisplayBOM(vChild,dic,rOut,lRow,lLevel+1)

NextvChild

EndSub



‘2014-11-17

‘http://club.excelhome.net/thread-1165696-1-1.html

PublicArr,d,d1,k,t

Sublqxs()

Dimi&,Brr,k2,t2,j&,aa,a

Setd=CreateObject("Scripting.Dictionary")

Setd1=CreateObject("Scripting.Dictionary")

Sheet1.Activate

[a:a].ClearContents

Myr=Cells(Rows.Count,2).End(xlUp).Row

Arr=Range("b1:b"&Myr)

ReDimBrr(1ToUBound(Arr),1To1)

Fori=1ToUBound(Arr)

n=Len(Left(Arr(i,1),Len(Arr(i,1))-4))

d(n)=d(n)&i&","

Next

k=d.keys:t=d.items

Fori=0ToUBound(k)

Ifi=0Then

Callyy0(t(i),i)

Else

Callyy(t(i),i)

EndIf

Next

EndSub



Subyy(tt,c)

Dimk1,t1,t2,j&,aa,sj,i&,m&

t1=Left(t(c-1),Len(t(c-1))-1)''上一级所在的行

t2=Left(tt,Len(tt)-1)''本级所在的行

IfInStr(t2,",")Then

bb=Split(t2,",")

Forj=0ToUBound(bb)

IfInStr(t1,",")Then

aa=Split(t1,",")

Fori=UBound(aa)To0Step-1

IfVal(bb(j))>Val(aa(i))Then

Ifsj<>aa(i)Thenm=0

sj=aa(i)''sj-上级;

m=m+1:Cells(bb(j),1)=Cells(sj,1)&"."&m

ExitFor

EndIf

Next

Else

IfVal(bb(j))>Val(t1)Then

Ifsj<>t1Thenm=0

sj=t1''sj-上级;

m=m+1:Cells(bb(j),1)=Cells(sj,1)&"."&m

ExitFor

EndIf

EndIf

Next

Else

sj=t2-1:Cells(t2,1)=Cells(sj,1)&".1"

EndIf

EndSub



Subyy0(tt,c)''第1级时

Dimt1,bb,j&,m&

t1=Left(tt,Len(tt)-1)

IfInStr(t1,",")Then

bb=Split(t1,",")

Forj=0ToUBound(bb)

m=m+1

Cells(bb(j),1)=m

Next

Else

Cells(t1,1)=1

EndIf

EndSub



16,BOM算法(数量汇总)

‘2015-9-8

‘http://club.excelhome.net/thread-1228305-1-1.html

PublicArr,d,dic,k,t

Sublqxs()

Dimi&,k2,t2,j&,aa,a

Application.ScreenUpdating=False

Setd=CreateObject("Scripting.Dictionary")

Setdic=CreateObject("Scripting.Dictionary")

Sheet1.Activate

Arr=[a1].CurrentRegion

Fori=5ToUBound(Arr)

Forj=2To6

IfArr(i,j)<>""Then

d(CStr(Arr(i,j)))=d(CStr(Arr(i,j)))&i&",":ExitFor

EndIf

Next

Next

k=d.keys:t=d.items

Fori=UBound(k)To1Step-1

Ifi=0Then

Callyy0(t(i),i)

Else

Callyy(t(i),i)

EndIf

k2=dic.keys:t2=dic.items



ii=ii+1

t2(ii)=Left(t2(ii),Len(t2(ii))-1)

IfInStr(t2(ii),"|")Then

aa=Split(t2(ii),"|")

Forj=0ToUBound(aa)

a=Split(aa(j),",")''a(1)-本级数量,a(2)-上级行

Cells(a(2),29)=Cells(a(2),29)+Val(a(1))

Next

Else

a=Split(t2(ii),",")

Cells(a(2),29)=Val(a(1))

EndIf

Arr=[a1].CurrentRegion

Next

Application.ScreenUpdating=True

EndSub

Subyy(tt,c)

Dimk1,t1,t2,j&,aa,sj,gs,i&

t1=Left(t(c-1),Len(t(c-1))-1)''上一级所在的行

t2=Left(tt,Len(tt)-1)''本级所在的行

IfInStr(t2,",")Then

bb=Split(t2,",")

Forj=0ToUBound(bb)

IfInStr(t1,",")Then

aa=Split(t1,",")

Fori=UBound(aa)To0Step-1

IfVal(bb(j))>Val(aa(i))Then

sj=aa(i):gs=Arr(bb(j),29)

Forx=30To34

IfArr(bb(j),x)<>""Thengs=gsArr(bb(j),x):ExitFor

Next

dic(k(c))=dic(k(c))&bb(j)&","&gs&","&sj&"|"

ExitFor

EndIf

Next

Else

sj=t1:gs=Arr(bb(j),29)

Forx=30To34

IfArr(bb(j),x)<>""Thengs=gsArr(bb(j),x):ExitFor

Next

dic(k(c))=dic(k(c))&bb(j)&","&gs&","&sj&"|"

EndIf

Next

Else

gs=Arr(t2,29):sj=t2-1

Forx=30To34

IfArr(t2,x)<>""Thengs=gsArr(t2,x):ExitFor

Next

dic(k(c))=dic(k(c))&t2&","&gs&","&sj&"|"

EndIf

EndSub



Subyy0(tt,c)''第1级时

Dimt1,bb,j&,sj,gs

t1=Left(tt,Len(tt)-1)

IfInStr(t1,",")Then

bb=Split(t1,",")

Forj=0ToUBound(bb)

sj=bb(j):gs=Arr(bb(j),29)

Forx=30To34

IfArr(bb(j),x)<>""Thengs=gsArr(bb(j),x):ExitFor

Next

dic(k(c))=dic(k(c))&bb(j)&","&gs&","&sj&"|"

Next

Else

gs=Arr(t1,4):sj=t1

Forx=30To34

IfArr(t1,x)<>""Thengs=gsArr(t1,x):ExitFor

Next

dic(k(c))=dic(k(c))&t1&","&gs&","&sj&"|"

EndIf

EndSub

17,BOM算法(适用于子件标准用量换算成最上层成品用量的算法)

‘2015-11-21

‘http://club.excelhome.net/thread-1242774-1-1.html

PublicArr,d,d1,k,t

Sublqxs()

''适用于子件标准用量换算成最上层成品用量的算法

Dimi&,Brr,k2,t2,j&,aa,a

Setd=CreateObject("Scripting.Dictionary")

Setd1=CreateObject("Scripting.Dictionary")

Sheet3.Activate

[e2:e50000]=""

Arr=[a1].CurrentRegion

ReDimBrr(1ToUBound(Arr),1To1)

Fori=2ToUBound(Arr)

d(Len(Arr(i,1)))=d(Len(Arr(i,1)))&i&","

Next

k=d.keys:t=d.items''将层级及行数做成字典

Fori=0ToUBound(k)

Ifi=0Then

Callyy0(t(i),i)

Else

Callyy(t(i),i)

EndIf

Next

k2=d1.keys:t2=d1.items'':c1=i



Fori=0ToUBound(k2)''从最上级开始

Ifi=0Then

t2(i)=Left(t2(i),Len(t2(i))-1)

IfInStr(t2(i),"|")Then

aa=Split(t2(i),"|")

Forj=0ToUBound(aa)

a=Split(aa(j),",")''a(0)-本级行,a(2)-上级行

Brr(a(0),1)=Arr(a(0),4)''本身数量

Next

Else

a=Split(t2(i),",")

Brr(a(0),1)=Arr(a(0),4)

EndIf

Else

t2(i)=Left(t2(i),Len(t2(i))-1)

IfInStr(t2(i),"|")Then

aa=Split(t2(i),"|")

Forj=0ToUBound(aa)

a=Split(aa(j),",")''a(0)-本级行,a(2)-上级行

Brr(a(0),1)=Brr(a(0),1)+Arr(a(0),4)Brr(a(2),1)''本身数量x上一级数量

Next

Else

a=Split(t2(i),",")

Brr(a(0),1)=Brr(a(0),1)+Arr(a(0),4)Brr(a(2),1)

EndIf

EndIf

Next

Range("e1:e"&UBound(Arr))=Brr

EndSub



Yy0和yy子过程同上面1

18,BOM算法(数量汇总,递归)



‘2016-2-24

‘http://club.excelhome.net/thread-1260544-1-1.html

Dimn&,d,d1

Sublqxs1()

DimArr,t1

Dimk,t,i&,ii&,k1,aa,bb,j&,sl

Setd=CreateObject("Scripting.Dictionary")

Setd1=CreateObject("Scripting.Dictionary")

Application.ScreenUpdating=False

Sheet2.Activate

[a2:c5000].ClearContents

Arr=Sheet1.[a1].CurrentRegion

Fori=2ToUBound(Arr)

d(Arr(i,1))=d(Arr(i,1))&Arr(i,2)&","

d1(Arr(i,1))=d1(Arr(i,1))&Arr(i,3)&","

Next

k=d.keys:t=d.items

k1=d1.keys:t1=d1.items:n=2

Fori=0ToUBound(k)

t(i)=Left(t(i),Len(t(i))-1)

t1(i)=Left(t1(i),Len(t1(i))-1)

Cells(n,1)=k(i)

IfInStr(t(i),",")Then

aa=Split(t(i),",")

bb=Split(t1(i),",")

Forj=0ToUBound(aa)

Callyyy(aa(j),n,bb(j),bb(j))

Next

Else

Callyyy(t(i),n,t1(i),t1(i))

EndIf

Next

Application.ScreenUpdating=True

EndSub



Subyyy(a,n,b,s)

Dimtt,tt1,aa,bb,j&

Ifd.exists(a)Then

tt=d(a):tt1=d1(a)

tt=Left(tt,Len(tt)-1)

tt1=Left(tt1,Len(tt1)-1)

IfInStr(tt,",")Then

aa=Split(tt,",")

bb=Split(tt1,",")

Forj=0ToUBound(aa)

Callyyy(aa(j),n,bb(j),sbb(j))

Next

EndIf

Else

IfCells(n,1)=""ThenCells(n,1)=Cells(n-1,1).Value

Cells(n,2)=a:Cells(n,3)=s:n=n+1

ExitSub

EndIf

EndSub

19,BOM算法(单价、金额)

‘2016-3-12

‘http://club.excelhome.net/forum.php?mod=viewthread&tid=1264018&page=1#pid8591142

PublicArr,d,d1,k,t

Sublqxs()

Dimi&,k2,t2,j&,aa,a,Myr&

Setd=CreateObject("Scripting.Dictionary")

Setd1=CreateObject("Scripting.Dictionary")

Sheet1.Activate

Myr=Cells(Rows.Count,1).End(xlUp).Row

Range("h9:h"&Myr).ClearContents

Arr=Range("a9:j"&Myr)

Fori=1ToUBound(Arr)

n=Len(Arr(i,1))-11

d(n)=d(n)&i&","

Next

k=d.keys:t=d.items

Fori=UBound(k)To0Step-1

Ifi=0Then

tt2=yy0(t(i),i)

Else

tt2=yy(t(i),i)

EndIf

Callss(tt2)

Next

Fori=1ToUBound(Arr)

Arr(i,8)=Arr(i,7)Arr(i,6)

Next

Range("a9:h"&Myr)=Arr

EndSub

Subss(tt2)

tt2=Left(tt2,Len(tt2)-1)

IfInStr(tt2,"|")Then

aa=Split(tt2,"|")

Forj=0ToUBound(aa)

a=Split(aa(j),",")''a(0)-本级行,a(2)-上级行,a(1)-本级单价

Arr(a(2),7)=Arr(a(2),7)+a(1)1''上级单价

Next

Else

a=Split(tt2,",")

Ifa(0)<>a(2)Then

Arr(a(2),7)=Arr(a(2),7)+a(1)1''上级单价

EndIf

EndIf



EndSub

Functionyy(tt,c)

Dimk1,t1,t2,j&,aa,sj,je,i&

t1=Left(t(c-1),Len(t(c-1))-1)''上一级所在的行

t2=Left(tt,Len(tt)-1)''本级所在的行

IfInStr(t2,",")Then

bb=Split(t2,",")

Forj=0ToUBound(bb)

IfInStr(t1,",")Then

aa=Split(t1,",")

Fori=UBound(aa)To0Step-1

IfVal(bb(j))>Val(aa(i))Then

sj=aa(i):je=Arr(bb(j),7)Arr(bb(j),6)

d1(k(c))=d1(k(c))&bb(j)&","&je&","&sj&"|"

ExitFor

EndIf

Next

Else

sj=t1:je=Arr(bb(j),7)Arr(bb(j),6)

d1(k(c))=d1(k(c))&bb(j)&","&je&","&sj&"|"

EndIf

Next

Else

je=Arr(t2,7)Arr(t2,6):sj=t2-1

d1(k(c))=d1(k(c))&t2&","&je&","&sj&"|"

EndIf

yy=d1(k(c))

EndFunction



Functionyy0(tt,c)''第1级时

Dimt1,bb,j&,sj,je

t1=Left(tt,Len(tt)-1)

IfInStr(t1,",")Then

bb=Split(t1,",")

Forj=0ToUBound(bb)

sj=bb(j):je=Arr(bb(j),7)Arr(bb(j),6)

d1(k(c))=d1(k(c))&bb(j)&","&je&","&sj&"|"

Next

Else

je=Arr(t1,7)Arr(t1,6):sj=t1

d1(k(c))=d1(k(c))&t1&","&je&","&sj&"|"

EndIf

yy0=d1(k(c))

EndFunction

20,BOM替代

‘2016/5/20

‘http://club.excelhome.net/thread-1278941-1-1.html

DimArr,d,n&,Brr,dh

Sublqxs()

Dimi&,k,t

Setd=CreateObject("Scripting.Dictionary")

[g25:l50000]=""

Arr=[b1].CurrentRegion

ReDimBrr(1To5000,1To5)

Fori=3ToUBound(Arr)

d(Arr(i,1))=d(Arr(i,1))&i&","

Next

k=d.keys:t=d.items:n=0

Fori=0ToUBound(k)

Callyy(t(i),n)

Next

[g25].Resize(n,5)=Brr

EndSub



Subyy(tt,n)

Dimt2,j&,bb,t1

t2=Left(tt,Len(tt)-1)

IfInStr(t2,",")Then

bb=Split(t2,",")

Forj=0ToUBound(bb)

IfArr(bb(j),3)="M"Then

t1=d(Arr(bb(j),2)):dh=Arr(bb(j),4)

Callyy0(t1,n,bb(j),Arr(bb(j),1),dh)

Else

n=n+1

Brr(n,1)=Arr(bb(j),1):Brr(n,2)=Arr(bb(j),2)

Brr(n,3)="P":Brr(n,5)=Arr(bb(j),5)

Brr(n,4)=Arr(bb(j),4)

EndIf

Next

Else

IfArr(t2,3)="M"Then

tt=d(Arr(t2,2)):dh=dhArr(t2,4)

Callyy0(tt,n,t2,mj,dh)

Else

n=n+1

Brr(n,1)=mj:Brr(n,2)=Arr(t2,2)

Brr(n,3)="P":Brr(n,5)=Arr(m,2)

Brr(n,4)=dhArr(t2,4)

EndIf

EndIf

EndSub



Subyy0(tt,n,m,mj,dh)

Dimt1,bb,j&

t1=Left(tt,Len(tt)-1)

IfInStr(t1,",")Then

bb=Split(t1,",")

Forj=0ToUBound(bb)

IfArr(bb(j),3)="M"Then

tt=d(Arr(bb(j),2)):dh=dhArr(bb(j),4)

Callyy0(tt,n,bb(j),mj,dh)

Else

n=n+1

Brr(n,1)=mj:Brr(n,2)=Arr(bb(j),2)

Brr(n,3)="P":Brr(n,5)=Arr(m,2)

Brr(n,4)=dhArr(bb(j),4)

EndIf

Next

Else

IfArr(t1,3)="M"Then

tt=d(Arr(t1,2)):dh=dhArr(t1,4)

Callyy0(tt,n,t1,mj,dh)

Else

n=n+1

Brr(n,1)=mj:Brr(n,2)=Arr(t1,2)

Brr(n,3)="P":Brr(n,5)=Arr(m,2)

Brr(n,4)=dhArr(t1,4)

EndIf

EndIf

EndSub

21,BOM转父子表

‘2016-12-14

‘http://club.excelhome.net/forum.php?mod=viewthread&tid=1315401&page=1#pid8922946



PublicArr,d,d1,k,t

Sublqxs()

Dimi&,Brr,k2,t2,j&,aa,a

Setd=CreateObject("Scripting.Dictionary")

Setd1=CreateObject("Scripting.Dictionary")

[k2:m500].ClearContents

[k2:m500].Borders.LineStyle=xlNone

Myr=Cells(Rows.Count,6).End(xlUp).Row

Arr=Range("f1:h"&Myr)

ReDimBrr(1ToUBound(Arr),1To1)

Fori=2ToUBound(Arr)

n=Arr(i,1)

d(n)=d(n)&i&","

Next

k=d.keys:t=d.items

Fori=0ToUBound(k)

Ifi=0Then

Callyy0(t(i),i)

Else

Callyy(t(i),i)

EndIf

Next

k2=d1.keys:t2=d1.items:n=1:col=11

Fori=1ToUBound(k2)

t2(i)=Left(t2(i),Len(t2(i))-1)

IfInStr(t2(i),"|")Then

aa=Split(t2(i),"|")

Forj=0ToUBound(aa)

a=Split(aa(j),",")''a(0)-本级行,a(2)-上级行,a(1)-数量

n=n+1

Cells(n,col)=Arr(a(2),2)

Cells(n,col+1)=Arr(a(0),2)

Cells(n,col+2)=a(1)

Next

Else

a=Split(t2(i),",")

n=n+1

Cells(n,col)=Arr(a(2),2)

Cells(n,col+1)=Arr(a(0),2)

Cells(n,col+2)=a(1)

EndIf

Next

[k1].CurrentRegion.Borders.LineStyle=1

ActiveWindow.DisplayZeros=False



EndSub



Subyy(tt,c)

Dimk1,t1,t2,j&,aa,sj,gs,i&

t1=Left(t(c-1),Len(t(c-1))-1)''上一级所在的行

t2=Left(tt,Len(tt)-1)''本级所在的行

IfInStr(t2,",")Then

bb=Split(t2,",")

Forj=0ToUBound(bb)

IfInStr(t1,",")Then

aa=Split(t1,",")

Fori=UBound(aa)To0Step-1

IfVal(bb(j))>Val(aa(i))Then

sj=aa(i):gs=Arr(bb(j),3)

d1(k(c))=d1(k(c))&bb(j)&","&gs&","&sj&"|"

ExitFor

EndIf

Next

Else

sj=t1:gs=Arr(bb(j),3)

d1(k(c))=d1(k(c))&bb(j)&","&gs&","&sj&"|"

EndIf

Next

Else

gs=Arr(t2,3):sj=t2-1

d1(k(c))=d1(k(c))&t2&","&gs&","&sj&"|"

EndIf

EndSub



Subyy0(tt,c)''第1级时

Dimt1,bb,j&,sj,gs

t1=Left(tt,Len(tt)-1)

IfInStr(t1,",")Then

bb=Split(t1,",")

Forj=0ToUBound(bb)

sj=bb(j):gs=Arr(bb(j),3)

d1(k(c))=d1(k(c))&bb(j)&","&gs&","&sj&"|"

Next

Else

gs=Arr(t1,3):sj=t1

d1(k(c))=d1(k(c))&t1&","&gs&","&sj&"|"

EndIf

EndSub























献花(0)
+1
(本文系蓝桥玄霜首藏)