Excel精英培训网

 找回密码
 注册
数据透视表40+个常用小技巧,让你一次学会!
楼主: fxb2015

[已解决]Excel VBA按多个条件删除行(求助高手)

[复制链接]
 楼主| 发表于 2015-12-29 17:37 | 显示全部楼层
grf1973 发表于 2015-12-29 14:22
代码第21句应改成 d(i)=""
上楼代码运行结果和你模拟结果相同。

谢谢grf1973老师,确实是为了冲掉尽可能多的行,但是,有先后条件,如果合并后的关键字所有负数之和刚好等于正数中最小正数时,优先删除。我把问题描述再详细点。
要求详见本楼的“根据数量正负删除符合条件的行.rar”中的工作表中,另外,我提供一个VBA代码思路(仅供参考):
在本楼上传的附件的“材料表”工作表中,用数组法或字典法从第三行起把G列、I列、J列并为一个关键字,然后删掉重复关键字而留下不重复关键字,然后对每一个不重复关键字对J列进行所有负数求和(设为x)、正数求和(设为y),同时找出每一个关键字所有正数中的最小正数(设为z):
(1)如果x+z=m>0,就删掉该关键字的所有负数行,把m值赋予z并保留z所在的行,其余正数行保留。
(2)如果x+z=n=0,就删掉该关键字的所有负数行,删掉最小正数z这一行,其余正数行保留。
(3)如果x+z=p<0,则分为以下情况:
      <1>   查找 该关键字的所有负数行,如有任一个负数与所有正数行的任一个正数相加等于零,那么删掉该负数行和该正数行,其余正数行保留。
      <2>   用x与所有正数的任一正数相加等于零,则删掉所有负数行和该正数行,其余行保留。
      <3>   如果x+y=0,则删掉所有正数行和所有负数行。当然,所有负数中的任意几个负数之和与所有正数中的任意几个正数之和相加等于零,那么这任意几个负数行、任意几个正数行全部删掉,其余行保留。
      <4>   如果每一个关键字同时出现<1>、<2>、<3> 这三种情况,先执行<1>,再执行<2>,最后执行<3>
               要是<1>、<2>、<3>都不出现,则用所有正数行的正数按从小打到进行累加,然后再用每个累加的数与x相加直到其结果大于零时,就停止累加。同时把累加到的最后这个正数改为累加结果,同时删掉所有负数行以及最后这个正数行前面的正数行。比如某关键字有正数q1<q2<q3<q4......,那么用q1+q2+x=j1,q1+q2+q3+x=j2,q1+q2+q3+q4+x=j3,如果j1、j2、j3中j2大于零时,则把j2的值赋予给q3并保留q3所在的行(q4行也保留),q1和q2这两行、所有负数行删掉;如果j1、j2、j3中j3大于零时,则把把j3的值赋予给q4并保留q4所在的行,q1、q2、q3这三行以及所有负数行删掉,以此类推。

在大条件(1)、(2)、(3)这3个条件中,优先考虑条件(1),然后再考虑条件(2),最后才考虑条件(3).
【备注】经过(1)、(2)、(3)这3个条件进行行删除后,最后不会出现负数行(因为所有负数行都会被正数抵消),因此可不用考虑x+y<0的情况。

根据数量正负删除符合条件的行.rar

12.25 KB, 下载次数: 1

excel精英培训的微信平台,每天都会发送excel学习教程和资料。扫一扫明天就可以收到新教程
回复

使用道具 举报

发表于 2015-12-29 20:08 | 显示全部楼层
你为什么不试一下我的代码呢?排序过后基本满足你的要求了。
回复

使用道具 举报

 楼主| 发表于 2015-12-30 09:08 | 显示全部楼层
grf1973 发表于 2015-12-29 14:22
代码第21句应改成 d(i)=""
上楼代码运行结果和你模拟结果相同。

试了grf1973老师的代码,可有些代码看不懂,为什么应该把代码第21句d(x) = d(x) & "," & i应改为d(i)=""呢?
回复

使用道具 举报

 楼主| 发表于 2015-12-30 12:57 | 显示全部楼层
本帖最后由 fxb2015 于 2015-12-30 13:02 编辑
grf1973 发表于 2015-12-29 20:08
你为什么不试一下我的代码呢?排序过后基本满足你的要求了。

grf1973 老师,你的代码已满足1楼的要求,但是又增加一个条件,代码该怎么新改写呢,条件是:
以“名称+计量单位+单价”为关键字,如果某一关键字含有N个单据编号,其中任意一个单据编号的数量全是负数,又有另外一个单据编号的数量全是正数,这两个单据编号数量的正数总和与数量的负数总和相加等于零,那么就优先删掉这两个单据编号的所有行,若是还有负数没冲掉,剩下的负数不能冲掉其他单据编号的话,也就执行9楼的代码——即同其余单据编号的数量的正数,从小到大进行冲销,直到负数被全部冲销为止,最后删掉负数行,保留正数行。

思考:是不是要以“单据名称+名称+计量单位+单价”为关键字加以判断,如果满足上述条件就调用新改写的代码,否则就执行9楼的代码?

最终目的:首先尽可能冲掉更多的单据编号,如果单据编号都冲不掉——就尽可能按正数从小到大冲掉更多的行。
希望
grf1973 老师再次帮忙~谢谢![em27]
回复

使用道具 举报

发表于 2015-12-30 13:38 | 显示全部楼层
fxb2015 发表于 2015-12-30 09:08
试了grf1973老师的代码,可有些代码看不懂,为什么应该把代码第21句d(x) = d(x) & "," & i应改为d(i)=""呢 ...

第21句本应该是d(i)="",就是把该删除的行数放到字典d里。字典的key为行数。
而d(x) = d(x) & "," & i 是把该删除的行以字符串形式放时字典d里,字典的key为原关键词(三个条件)。之所以有这句完全是编制代码时从上复制下来后没改过来。
其实如果原数据里没有数量为0的行,完全可以无视。
回复

使用道具 举报

发表于 2015-12-30 13:39 | 显示全部楼层
fxb2015 发表于 2015-12-30 12:57
grf1973 老师,你的代码已满足1楼的要求,但是又增加一个条件,代码该怎么新改写呢,条件是:
以“名称+ ...

这个可以分两步:
    1、以四个条件为key,运行一遍代码。
    2、以三个条件为key,再运行一遍代码。
回复

使用道具 举报

 楼主| 发表于 2015-12-30 14:13 | 显示全部楼层
grf1973 发表于 2015-12-30 13:39
这个可以分两步:
    1、以四个条件为key,运行一遍代码。
    2、以三个条件为key,再运行一遍代码。 ...

grf1973老师,是不是在9楼代码的基础上,先把key换成四个条件运行后,再换成三个条件再运行一遍?
回复

使用道具 举报

发表于 2015-12-30 14:29 | 显示全部楼层
是的。但要以第一次运行结果作为第二次运行的源数组Arr。
回复

使用道具 举报

发表于 2015-12-30 14:47 | 显示全部楼层
用参数的形式调用了原代码。当nn=4时4个条件。

材料统计.rar

21.06 KB, 下载次数: 3

回复

使用道具 举报

 楼主| 发表于 2015-12-30 14:48 | 显示全部楼层
本帖最后由 fxb2015 于 2015-12-30 15:07 编辑
grf1973 发表于 2015-12-30 14:29
是的。但要以第一次运行结果作为第二次运行的源数组Arr。

grf1973老师,还是不行呢,看看本楼上传的附件,查下问题出在哪里呢

根据数量正负删除符合条件的行(4个key与3个key).rar

26.12 KB, 下载次数: 1

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|Excel精英培训 ( 豫ICP备11015029号 )

GMT+8, 2024-5-7 23:13 , Processed in 0.302608 second(s), 11 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表