pk富10四个码二期必能中方法;代码的使用方法?

【图片】玩三国志11你不得不用修改器---sire修改器【三国志11威力加强版吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0可签7级以上的吧50个
本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:95,238贴子:
玩三国志11你不得不用修改器---sire修改器
还在为骑神推小推车而烦恼么?还在为特技少儿无聊么?还在因制作新的mod而感到311不合适么?赶紧用sire修改器吧
孩子,洗洗睡吧
我在这里介绍下sire修改器吧,这个修改器是百度贴吧吧友ryan_knight_12做的,如果你也混游侠的话,那 流氓软件王 你一定听说过,这里是sire的下载地址http: //cyehua.ys 168.com/
这里有全部的sire版本http: //knight12.ys 168.com/ 这是作者rk的网盘(注意空格)
以下是sire使用的一些帮助文档,当然你也可以下载大汉扶菊使的sire帮助文档
sire修改器只只是pk1.1版的,所以pk1.2版的和原版没法使用了 当你已经进入游戏后,打开修改器会看到上图的样子。左上角最左处是载入你修改器配置信息的,左上角第二处是保存你修改器配置信息的,左上角第三处是“默认配置”按钮,改乱了的,可以通过此按钮回到最初默认值。(目录下会多一个default.sire的只读文件,请勿删除)左上角第四处是输入法切换为简体输入的选项左上角第五处是输入法切换为繁体输入的选项左上角第六处是“打开游戏并自动应用修改”按钮,点击该按钮后,自动打开SAN11PK.EXE(第一次会要求用户指定路径),打开5秒之后自动应用当前的修改配置。左上角第七处是武将属性修改界面(新建特技必须是在特技定制页面设置好)
第一页:修改武将与部队的界面1,最要注意的是左下角的宝物增加能力和特技这一项:将311比较鸡肋的宝物提升到和39 310一个高度啊,注意:宝物加的特技不能是嵌套特技,只能是原特技。2,右边中间部分是各种规则的计算,喜欢统定攻防或者武定攻 甚至魅力定攻防(萌战无双mod)
第二页:兵种与战法页1.在伤害修正规则中,可以弥补统定攻防中武力变得只能单挑,这样可以统定攻防,武力提高伤害。2,兵种相克指数:让戟兵更肉,骑兵更加犀利。最下面的骑兵攻击前每移动一格伤害加成:这让骑兵更加符合历史
第三页:计略与陷阱
第四页:城市与港口1,注意城市士兵上限不要超过100w2,选取据点自动攻击后,神马一兵流克制的很厉害有木有啊,强弩后城市自动攻击的射程+1
第五页:工事与光环最重要的光环页啊1,所谓基础光环 就是你必须有这个光环 其他的光环才有效 以图为例 如果你统帅不到90 也就是没有基础光环 那么 哪怕你其他四项属性都是120 也没用 然后 如果基本光环范围设为1 那么一级光环范围为1格 二级光环范围为2格 三级光环则为3格 ,2,基础光环会为我们周围的部队增加攻防 以图为例 基础光环的阙值为90 比例为50% 最小攻防增加值为5 公式(X-90)*50+5拿120统举个例子吧 则增加的攻防为(120-90)*50%+5=20 也就说120统能为周围3格的部队增加20点攻防其他光环以此类推,3,光环只有主将才有 你副将统再高也是没有滴 如果战场上有多个超过90统帅的武将:首先 君主若有光环 则君主最大 如果君主没有 则按官职大小来决定取谁的基础光环 武官大于文官 而丞相 司空 太尉 司徒 这四个官职是最大的 如果官职同等 则取统帅高的那位 最后如果最大光环者若没有别的光环 则会由附近的第二光环提供光环 如A和B在一起 A本身只有攻防光环而B有其他所有光环 所以其他光环会由B补充 4,然后是军魂和武干的解释 军魂是全部光环的效果增加50% 也就是说,120统增加20攻防 如果有军魂 则会增加30攻防 而武干则是光环范围+1 如果持有武干者统帅不到90 则会获得1级光环 你可以理解为他本身光环是0 +1后变为15,如果光环提供者在战场上被扰乱的话 则失去光环效果 所以 一定要注意保护好光环提供者6,最后如果一个五维都是120的武将 带有军魂 武干 能为战场提供多少补助呢 答案是:他能为4格以内的部队增加30点攻防 30%的战法成功率 18%的战法暴击率 30%的计略成功率 18%的计略暴击率 60%的辅助攻击和12点回气
第7页:内政与设施1,增加内政用地时不要将用地放到森林上,会跳出游戏。一级自动变3级,减少了内政点来点去,大大提高311可玩性。2,经济收入:让ai随便建设也没事的一项
第8页:特技效果1,修改气力参数,威风昂扬雄起啊2,这有个bug 及连击对战法有效后会所有兵种都会单挑,不过可以用以下办法解决a,打开pkme修改器,启动修改引擎后即可。b,打开sire,按你修改好的修改游戏后 就不会出现所有兵种都单挑了(坏处:骑兵可不单挑了)注意顺序,不然游戏会跳出
第九页:特技定制注意:特技嵌套无效,所以最多9个特技
一次都没用过咋办。。。。。。。
1、(120号)兵圣基本解释:所受物力伤害减半特技评级:5星特技分类:战斗类-&防御适用范围:一切对持有“兵圣”特技部队的物力攻击,包括普通攻击、战法攻击、援助攻击、部队/据点反击、箭塔/投石攻击、伏兵攻击;不包括火(火计、火矢附件火伤、落雷附加火伤、木兽喷射附加火伤)、火陷阱、落石、落雷。兵圣在据点中无效。适用武将:高统武将适配兵种:戟兵特技搭配:1)铁壁——不会被移动的肉盾2)踏破——除了落雷和火,其它伤害都减半3)藤甲——物力伤害减为25%,宜再搭配踏破4)怒发——一回合有机会加很多气5)百战——旋风,旋风,再旋风特别注意:“兵圣”与“藤甲”一样,搭配金刚无效果,“金刚”搭配“兵圣”后,普攻免伤阈值由500下降为250。2、(121号)兵神基本解释:所受战法成功率减为原来的25%特技评级:4星特技分类:战斗类-&防御适用范围:一切对持有“兵神”特技部队的战法攻击,包括兵器攻击,其成功率都减为原来的四分之一。“兵神”计算是在计算战法成功率的最后进行,故持有“兵仙”特技的部队如果统率高于“兵神”部队,那么战法成功率也只有25%。适用武将:高统武将适配兵种:各类兵种特技搭配:1)金刚——格档普攻,前提是部队防御足够高2)不屈——格档普攻,单兵少时才有效,不是很靠谱3)兵圣——使普攻伤害也减半,但显得浪费,不如两队单开
3、(122号)兵仙基本解释:对统率低于己方的部队战法必成功特技评级:4星特技分类:战斗类-&攻击适用范围:一切部队统率低于“兵仙”持有者的部队,所谓部队统率并不等于部队中的最高统率,而是主将统率加上副将的关系修正。“兵仙”计算是在计算战法成功率的倒数第二进行。同时,对建筑的战法(如乱射),由于战法施放对象不是部队,“兵仙”特技是无效的。适用武将:高统武将适配兵种:各类兵种作者点评:由于游戏原来的战法成功率本身就比较高,因此兵仙的作用相比于兵圣、兵神直接带来的明显防御效果而言并不是很突出,但如果结合SIRE降低战法基本成功率的话,兵仙特技将会非常有用。特技搭配:1)霸王、斗神、枪神、枪将——枪系控制类部队,免去SL的麻烦2)疾驰——骑系控制类部队,免去SL的麻烦3)弓神/弓将(弓S)——强力又稳定的输出部队4、(123号)战神基本解释:战法爆击伤害翻倍特技评级:5星特技分类:战斗类-&攻击适用范围:只要战法成功,无论面对部队或是建筑,皆能获得伤害翻倍效果。对于群杀战法,只对攻击对象本身,及固定方位的1个波及点有伤害翻倍效果。适用武将:任何武将适配兵种:枪、骑(由于爆击翻倍效果对群杀只适用于2个点,因此更适合使用枪、骑打造强力点杀部队)特技搭配:1)必暴类特技——由于战神本身不确保必暴,因此必须配合必暴类特技才能发挥其极至的效果。5、(124号)战将基本解释:对防御力低于己方攻击力的部队战法成功必爆击特技评级:3星
特技分类:战斗类-&攻击适用范围:面对对象是敌方部队,对建筑无效。由于比较的是部队属性,故战将特技持有者本身的属性并不是非常重要,可以作为副将搭配出战。适用武将:任何武将适配兵种:枪(虽然枪的攻击力是第二高,但爆击主要还是为了晕人)特技搭配:1)战神——由于战神本身不确保必暴,战将特技几乎就是为了搭配战神而度身定做的。6、(125号)巧变基本解释:可无视地形限制施放战法特技评级:3星特技分类:战斗类-&辅助适用范围:任何兵种,特别要指出的是,巧变涵盖了部分射手的功能,使弩兵能在树林里射击(不能让弓兵普攻森林的部队)。适用武将:任何武将适配兵种:骑、枪(这两种兵种地形限制比较大)特技搭配:1)疾驰——使骑兵在南方的森林和湿地中依然能够晕人2)枪神、枪将——在沙地中使用螺旋刺来晕人
7、(126号)游侠基本解释:己方士兵少于对方一半时,战法成功必爆击特技评级:3星特技分类:战斗类-&攻击适用范围:面对对象是敌方部队,对建筑无效,哪怕是据点,也不会去比较兵数。由于比较的是兵力,故游侠特技持有者本身的属性并不是非常重要,可以作为副将搭配出战。适用武将:任何武将适配兵种:枪(爆击主要还是为了晕人)作者点评:由于此特技要求兵力少于对方的一半,故部队不能带太多兵,于是如何保证该部队的安全,使之不致溃灭显得尤为重要。特技搭配:1)兵圣——对本来兵力就较少的部队提供防御能力2)兵神+不屈——同样是为了保证部队能在战场上的持久性8、(127号)百战基本解释:战法耗费气力20%特技评级:4星特技分类:战斗类-&辅助适用范围:对所有战法都有效适用武将:任何武将适配兵种:戟、弩(利用戟、弩进行大范围杀伤)特技搭配:1)戟神/戟将/戟S+遁走——旋风、旋风、再旋风2)弓神/弓将/弓S+神臂——乱射、乱射、再乱射9、(128号)狙击基本解释:施展射击战法时,可让敌将负伤特技评级:3星特技分类:战斗类-&辅助适用范围:对五种射击战法成功时有效:弩兵火矢、贯射、乱射;井栏火矢;水军火矢。如果是范围攻击,则对所有被攻击到的部队都有效。
适用武将:高武/统武将适配兵种:弩作者点评:最早的狙击是战法成功必伤,形成了一个乱射伤一大片的效果,所以后来将狙伤率增加量由原来的100%改为30%,由于弩兵战法原始的狙伤率大约在3%-5%,基本上等于1/3的狙伤率,确保贯射3支能够伤1支,乱射7支能够伤2支。特技搭配:1)弓神/弓将——配合爆击提高的狙伤几率,获得更高的狙伤率2)神臂——狙击远处的敌重要部队3)巧变/射手——狙击森林中的敌重要部队10、(129号)神臂基本解释:弩兵攻击射程+1特技评级:4星特技分类:战斗类-&辅助适用范围:无论对弩兵战法,还是弩兵普通攻击,还是弩兵还射,该射程增加量都有效果,但对兵器无效,对水军无效。适用武将:任何武将适配兵种:弩作者点评:和射程一样,在关键地点能够起到关键作用的特技,而由于弩兵有“乱射”战法,从而使“神臂”特技更为有用,守关/港时可用来大片杀伤敌未接近关/港口的部队。特技搭配:1)弓神/弓将——射更远,暴更多.....2)狙击——射更远,伤更多.....11、(130号)治军基本解释:物理攻击眩晕效果免疫特技评级:4星特技分类:战斗类-&防御适用范围:能够防止任何物力攻击带来的眩晕,包括螺旋突刺晕、疾驰晕、犄角晕,同时能够防止因兵少而产生的眩晕,以及“恫吓”特技带来的眩晕效果。但是对于计谋所带来的眩晕,如扰乱、伏兵、妖术没有效果,同样不能防止石兵八阵和火陷阱造成的眩晕。适用武将:任何武将适配兵种:任何兵种作者点评:强悍的防御特技,弥补了原版游戏中对物力晕无破解的缺陷,为打造极品的防御部队提供了可能。特技搭配:1)洞察——达成对异常状态的免疫最大化2)兵圣/兵神——顶在前面的超级肉盾12、(131号)坚城基本解释:守城时城防下降和士兵数下降减半特技评级:4星特技分类:战斗类-&防御适用范围:对特技持有武将“所属”的据点有效,而不是“所在”的据点有效,也就是说即时武将在外公干,也是有效的。注意:如果武将所属于某城市中,那对该城市下属的关、港是无效的,反之亦然。适用武将:任何武将适配兵种:据点中作者点评:结合城市自动攻击的功能,坚城将会是非常彪悍的守城特技,对玩家来说,超级难度抵御电脑初期的攻势将有更多选择。特技搭配:1)踏坡——弥补坚城对火陷阱伤害不减的缺陷。2)筑城——当开启筑城对城市耐久恢复有效后,拥有筑城+坚城的城市将使攻城者非常郁闷。
做的一手好广告
13、(132号)料敌基本解释:敌方计策成功率50%特技评级:3星特技分类:计略类适用范围:料敌对必中特技有效,也就是说神算、虚实对料敌也只有50%的计略成功率。适用武将:低智武将为优适配兵种:任何兵种特技搭配:1)反计——配上反计必中的效果之后,该组合会相当强大。14、(133号)陷阵基本解释:能对敌方施展的战法予以强势的反击特技评级:2星特技分类:战斗类-&攻击适用范围:强势反击的意思是100%的普攻伤害(战法成功的反伤默认是40%普攻伤害)。但“陷阵”只是对于能够反击的部队进行反击,对于远程攻击无反击(还射处外),对于“突袭”“强袭”,森林中有三级科技的枪兵,以及自己部队处于眩晕状态时,都不能形成反击。适用武将:任何武将适配兵种:戟(优先保证自己的防御,才能确保反击的输出)作者点评:一个普通的技能,反击的那点伤害对玩家来说根本不够看,但如果电脑部队有此特技,却又比较讨厌。当然,由于破解此特技的方法太多(如远程攻、眩晕后攻),所以此特技档次只是一般,可是名字很霸气!特技搭配:1)兵圣——确保自己的防御,以吸引敌方的围攻,借以累积反击的高输出。2)怒发——边反击边加气,等自己行动时就放旋风....3)血路——防止被抓15、(134号)恫吓基本解释:周围一格的武力低于己方的部队有50%几率陷入眩晕特技评级:4星特技分类:战斗类-&辅助适用范围:恫吓有四点限制:对方部队与本方部队相临;对方部队所属势力不与本方停战或同盟;本方部队不处于异常状态;特技持有者武力高于对方部队中所有武将(这个可以选,不过一般是武力)。适用武将:高武武将适配兵种:任何兵种作者点评:一个强势特技,不需要耗任何气力就可以使对方陷入眩晕,是防御时顶在最前方的顶级肉盾,唯一需要的是那么一点点的人品。特技搭配:1)遁走——便于到达最好的位置。2)血路——由于时常要与敌方多支部队贴身,所以要防止恫吓不发动是被群攻而被抓3)护卫——防止受伤造成的武力下降4)洞察/明镜/沉着/规律——防止异常状态5)治军——防止眩晕
16、(135号)破竹基本解释:击破一支敌军后,该敌军周围2格范围内所有敌军气力-20(范围和气力消减都可以改)特技评级:4星特技分类:战斗类-&辅助适用范围:只要击破一支部队,以该部队为圆心,2格为半径内的所有与被击破部队所属势力相同的部队都会无条件减少20气。同时击破多支部队,减气效果可叠加。与威风效果、扫讨效果可以叠加。适用武将:任何武将适配兵种:弩(击破敌中心部队+同时击破多支)作者点评:强力减气特技,与威风各有优势。破竹的好处是如果同时击破两支,则叠加减40气,依次推类,因此理论上存在一回合抽干气的可能性,而弱点是只在击破时起作用。另外,与威风一样,千万注意不要击破自己的部队....特技搭配:1)神臂、射程——便于击**于最优位置的敌军,使减气效果最大化。2)威风——可叠加,大范围减气效果更明显。 17,(136号)安民基本解释:攻破敌方城池后可保留全部内政设施。特技评定:2星特技分类:内政适用范围:破城最后一刀由带安民的特技的破城可保留全部内政设施,是种田流的福音,免了自己再一次盖房子了。特别是sire的设置下,农场不用围着谷仓了,市场也不用围着造币厂了,电脑瞎造建筑也不怕哦!适用武将:全部18,(137号)循吏基本解释:增加建设内政设施的速度。特技评定:2星特技分类:内政适用范围:开局建设时用处比较大,可以减让建设时间减半,种田流的又一钟爱。适用武将:高政武将。
19.(138号)贤哲基本解释:所属势力每月增加一定量的技巧值特技评定:2星特技分类:内政适用范围:读音是xianzhe,写做闲者~~没错 贤哲基本都是闲者,啥都不用干,就等着每个月发俸禄加技巧P就行了,多个贤哲可叠加。势力每月增加50点技巧值(超级难度会减半每人25点,可以调)适用范围:在家呆着没事的武将。20(139号)变法基本解释:每旬行动力恢复量增加,谷仓和造币厂作用提升为2倍特技评定:4星特技分类:内政适用范围:让特技评定:2星特技分类:内谷仓和造币厂由1.5倍变为2倍,这个效果只是和富豪和米道的综合体,但是另一属性:每回合+20点行动力很给力有木有,每回合20点的行动力意味着你每回合能多征一次兵,或者生产一次兵装,或者出两队兵。在积攒了足够的优势之后,碾压对手吧!适用武将:在家呆着没事的武将。
21(140号)法治基本解释:所在城治安不会下降特技评定:2星特技分类:内政适用范围:可避免征兵,换季及灾害降治安,治安高了收入高,也不必担忧贼和少数民族的威胁了,放大后方的神器啊,拥有此特技的武将出城也对所属城市有效,不过对灾害不是太好,没法巡查,不利于及早的消灭灾害啊适用武将:全部武将22(141号)后勤基本解释:所属据点的军队耗费军粮由据点供给一半特技评定:3星特技分类:内政适用范围:只要后勤所在城市,则从此城出击的部队,粮食一半由本城承担,远攻神器有木有啊,不过和1.25c的屯田冲突啊(1.25c屯田对城市有效,不减粮食,可1粮养活10w兵不过有后勤的话····1.26pre反而减弱屯田不会冲突)适用武将:全部武将23(142号)亲和基本解释:实行亲善所能提升的友好度加倍特技评定:2星特技分类:内政适用范围:可以让一次亲善效果加倍,想同盟的童鞋有福了(本人不怎么同盟亲善,对此特技没怎么理解)
适用武将:全部武将24(143号)圣人基本解释:登用无归属武将时必定成功特技评定:4星特技分类:内政适用范围:可以随意登用在野和已灭势力的俘虏武将,结合伯乐可偷ai城下的武将适用范围:全部武将25(144号)运筹基本解释:如果使用计策成功,则有机率可再行动一次(概率可调)特技评定:3星特技分类:计略适用范围:可以让高智武将拥有,计略成功后可以再次行动,不过和连环冲突,连环过后就不能再动了(可以钻空子,先用连环无效的计略,比如伏兵,内讧)。另外,运筹对运输队无效,不过其他部队可以用运筹来急行军适用武将:高智武将适用兵种:全部兵种特技搭配:神百运,虚百运,神连运(这个要注意)26(145号)激励基本解释:如果使用战法成功,则有机率可再行动一次(概率可调)特技评定:3星特技分类:战斗类》》辅助适用范围:当激励调到100后就是bug啊,连用2次战法,但是要注意气力啊
适用武将:任何武将适用兵种:任何兵种战法搭配:必爆战法+百战+激励(本人比较喜欢用弓兵,一个关口前守50年有木有)27(146号)伯乐基本解释:所在城市可以登用非己方势力所属城市的在野武将特技评定:3星特技分类:内政适用范围:伯乐是拥有武将的相性不是君主的,相性差可调。当2伯乐在一城时,只有一伯乐有效(id靠前的那个)适用武将:全部武将28(148号)军魂基本解释:统率光环带来的各种加成效果增为1.5倍特技评定:4星特技分类:补助适用范围:主将统超过你所设置的基本光环要求后,全部光环的效果*1.5(可参考光环的解说)适用武将:高统主将29(149号)武干基本解释:令未达到统率光环要求的主帅获得基础统率光环,否则光环范围加1格特技评定:4星特技分类:补助使用范围:主将统没达到基本光环要求的可得到基本光环,有基本光环的可以让其光环范围+1 (可参考光环的解说)适用武将:所有主将
第十页:其他1,去除针对部分原版三国武将的特殊处理——即是原本三国武将有得到一些加成,比如吕布、五虎、许诸等的单挑隐藏武力(另据代码分析结果,隐藏的骑兵强制单挑率和骑兵突死率可能并不存在,因为没发现对马超、夏侯敦等人在突死方面的特殊处理代码)2.出动部队策略:建议偏重防御3,每回合为ai自动增加资源,其中士兵要谨慎设置,这有可能会使电脑势力之间的吞并变得更难,另外如果设置了军马耗粮的话,军马也不要加得太多
如果你想了解sire的历史(从1.00到1.25c)可以看本帖
建议不要顶这贴 rk吧治理挖坟很厉害的
这是转自游侠的一些sire修改心得1,野外兵粮消耗绝不可以调高,否则电脑会在半路饿死。因为电脑不会多带粮,尤其是防御的时候。2,修改行动力时注意不同地形消耗,每回合移动不能小于三格,否则也会把AI饿死。3,城中耗粮基数也尽量不要改高,否则电脑会无视消耗疯狂征兵,最后都饿死城中~(AI是饿鬼吗?)4,移动力无论怎么调最高只能走11格(sire设定),但是超量的移动力在复杂地形时仍可以体现出来。注意移动力总量不要过高,即使有sire的限制仍然会死机。5,势力技能表如果修改了顺序后可能造成研究成功的动画不出现,即使是原有技能。这个不知道是不是,反正有两次被我发现了~6,贼势力如果给了黄巾国号,就变成黄巾军了~注意贼势力的特技什么都可以给,就是别给50%以上几率防战法的不屈,否则AI后方都会变成空城~别看不屈自己用处不大,贼势力有了它就会变成妖孽~7,在骑兵有移动攻击力加成的时候,疾驰如果改成伪退效果远高于混乱,一旦成功把敌人击退,在进攻就会再次攻击力加成,否则变成近战后骑兵特性就体现不出来了~8,207剧本如果等待不到曹操南征的剧情就直接修改剧本吧晋阳送给曹操,这样在剧本开始30日后剧情就会出现~这样更加符合历史~而且三顾,刘表之死等剧情更容易触发~9,如果火计的伤害效果没有提高,就尽量提高火计消耗气力,如果火计消耗过低,就会造成电脑的进攻全是放火,然后被推掉~10,AI不知道在什么条件下的判定,反正有很大几率无视出城的军队,而是自杀式的去攻城~所以如果只把城防调高或者攻击城塞力调低,AI就变成了白痴~11,AI绝对不会找不和以下的势力同盟,也永远不会退盟,所以如果想还原历史那么玩,尽量使用停战而不是同盟~12,特技的等级似乎会影响游戏中AI让谁独立出战,这个我只是猜的,大家如果能确定一下就非常感谢了~4级可能更容易单独出战???这个我不确定~13,AI的主动特技几乎都是废物,而被动特技非常NB,比如敌战法成功率降低,武力损耗减半,战法反击提高等~14,内政设施建设时间不宜过长,虽然提高游戏耐玩性,但是很容易造成人才匮乏的AI早早被灭。所以那个时间无上限的选项绝对不能选。15,敌将捕获率是无法调低的,只能调高,所以即使捕获率全是0,捕获敌将的几率仍然很高~解决办法就是把特技都添加血路,如此一来有特技武将就几乎不会被捕,除非单挑。而且无特技武将也很少独自带队~所以捕获率就降低了。16,宝物特技千万别忘了,只能添加原特技,原特技中自己添加的特技是无效的~17,如果把特技“捕获”几率调到0,然后把特技名称修改成自己喜欢的,然后添加一些自己的特技,就可以在势力能力研究后,让武将学习,虽然没有能力研究成功的动画,但是满足了后期武将特技单调的局面。其他能调成0的特技都可以这样,只是捕获和掠夺我从来不用~18,pkme和sire同时运行后,全战法单挑的几率会出现冲突,但是偶尔还是能出现的~到底怎么回事我也不知道~19,俸禄调过高没什么,但是会给初期的高爵位的AI势力造成困扰,因为俸禄太高,而且初期还需要建设设施。玩家自己嘛,开局就把官全撸了就结了。20,如果把攻城武器的价格调高,或者建造时间延长,记得把城市库存上线改成3-5个,这样就不会让AI成天到晚的浪费钱在那上面了,反正攻城武器从来也不会超过5个一齐出动,而且防御AI也不会使用
贴吧热议榜
使用签名档&&
保存至快速回贴1 / 125 页
查看: 315730|回复: 1239
常见字典用法集锦及代码详解
阅读权限100
在线时间 小时
& & & & & & & &
本帖已被收录到知识树中,索引项:
本帖最后由 moon2778 于
16:31 编辑
凡是上过学校的人都使用过字典,从新华字典、成语词典,到英汉字典以及各种各样数不胜数的专业字典,字典是上学必备的、经常查阅的工具书。有了它们,我们可以很方便的通过查找某个关键字,进而查到这个关键字的种种解释,非常快捷实用。
凡是上过EH论坛的想学习VBA里面字典用法的,几乎都看过研究过northwolves狼版主、oobird版主的有关字典的精华贴和经典代码。我也是从这里接触到和学习到字典的,在此,对他们表示深深的谢意,同时也对很多把字典用得出神入化的高手们致敬,从他们那里我们也学到了很多,也得到了提高。
字典对象只有4个属性和6个方法,相对其它的对象要简洁得多,而且容易理解使用方便,功能强大,运行速度非常快,效率极高。深受大家的喜爱。
本文希望通过对一些字典应用的典型实例的代码的详细解释来给初次接触字典和想要进一步了解字典用法的朋友提供一点备查的参考资料,希望大家能喜欢。
给代码注释估计是大家都怕做的,因为往往是出力不讨好的,稍不留神或者自己确实理解得不对,还会贻误他人。所以下面的这些注释如果有不对或者不妥当的地方,请大家跟帖时指正批评,及时改正。
字典的简介
字典(Dictionary)对象是微软Windows脚本语言中的一个很有用的对象。
附带提一下,有名的正则表达式(RegExp)对象和能方便处理驱动器、文件夹和文件的(FileSystemObject )对象也是微软Windows脚本语言中的一份子。
字典对象相当于一种联合数组,它是由具有唯一性的关键字(Key)和它的项(Item)联合组成。就好像一本字典书一样,是由很多生字和对它们对应的注解所组成。比如字典的“典”字的解释是这样的:
“典”字就是具有唯一性的关键字,后面的解释就是它的项,和“典”字联合组成一对数据。
常用关键字英汉对照:
Dictionary& && && && && & 字典
Key& && && && && && && && &关键字
Item& && && && && && && && &项,或者译为 条目
字典对象的方法有6个:Add方法、Keys方法、Items方法、Exists方法、Remove方法、RemoveAll方法。
向 Dictionary 对象中添加一个关键字项目对。
object.Add (key, item)
必选项。总是一个 Dictionary 对象的名称。
必选项。与被添加的 item 相关联的 key。
必选项。与被添加的 key 相关联的 item。
如果 key 已经存在,那么将导致一个错误。
常用语句:
Set d = CreateObject(&Scripting.Dictionary&)
d.Add &a&, &Athens&& &
d.Add &b&, &Belgrade&
d.Add &c&, &Cairo&
1、Dim d :创建变量,也称为声明变量。变量d声明为可变型数据类型(Variant),d后面没有写数据类型,默认就是可变型数据类型(Variant)。也有写成Dim d As Object的,声明为对象。
2、Set d = CreateObject(&Scripting.Dictionary&):创建字典对象,并把字典对象赋给变量d。这是最常用的一句代码。所谓的“后期绑定”。用了这句代码就不用先引用c:\windows\system32\scrrun.dll了。
3、d.Add &a&, &Athens&:添加一关键字”a”和对应于它的项”Athens”。
4、d.Add &b&, “Belgrade”:添加一关键字”b”和对应于它的项”Belgrade”。
5、d.Add &c&, “Cairo”:添加一关键字”c”和对应于它的项”Cairo”。
Exists方法
如果 Dictionary 对象中存在所指定的关键字则返回 true,否则返回 false。
object.Exists(key)
必选项。总是一个 Dictionary 对象的名称。
必选项。需要在 Dictionary 对象中搜索的 key 值。
常用语句:
Dim d, msg$& &
& &Set d = CreateObject(&Scripting.Dictionary&)
& &d.Add &a&, &Athens&& &
& &d.Add &b&, &Belgrade&
& &d.Add &c&, &Cairo&
& &If d.Exists(&c&) Then
& && &msg = &指定的关键字已经存在。&
& && &msg = &指定的关键字不存在。&
1、Dim d, msg$ :声明变量,d见前例;msg$ 声明为字符串数据类型(String),一般写法为Dim msg As String。String 的类型声明字符为美元号 ($)。
2、If d.Exists(&c&) Then:如果字典中存在关键字”c”,那么执行下面的语句。
3、msg = &指定的关键字已经存在。& :把&指定的关键字已经存在。&字符串赋给变量msg。
4、Else :否则执行下面的语句。
5、msg = &指定的关键字不存在。& :把&指定的关键字不存在。&字符串赋给变量msg。
6、End If :结束If …Else…Endif判断。
返回一个数组,其中包含了一个 Dictionary 对象中的全部现有的关键字。
object.Keys( )
其中 object 总是一个 Dictionary 对象的名称。
常用语句:
Dim d, k& &
& &Set d = CreateObject(&Scripting.Dictionary&)
& &d.Add &a&, &Athens&& &
& &d.Add &b&, &Belgrade&
& &d.Add &c&, &Cairo&
& &k=d.Keys
& &[B1].Resize(d.Count,1)=Application.Transpose(k)
1、Dim d, k :声明变量,d见前例;k默认是可变型数据类型(Variant)。
2、k=d.Keys:把字典中存在的所有的关键字赋给变量k。得到的是一个一维数组,下限为0,上限为d.Count-1。这是数组的默认形式。
3、[B1].Resize(d.Count,1)=Application.Transpose(k) :这句代码是很常用很经典的代码,所以这里要多说一些。
Resize是Range对象的一个属性,用于调整指定区域的大小,它有两个参数,第一个是行数,本例是d.Count,指的是字典中关键字的数量,整本字典中有多少个关键字,本例d.Count=3,因为有3个关键字。呵呵,是不是说多了。
第二个是列数,本例是1。这样=左边的意思就是:把一个单元格B1调整为以B1开始的一列单元格区域,行数等于字典中关键字的数量d.Count,就是把单元格B1调整为单元格区域B1:B3了。
=右边的k是个一维数组,是水平排列的,我们知道Excel工作表函数里面有个转置函数Transpose,用它可以把水平排列的置换成竖向排列。但是在VBA中不能直接使用该工作表函数,需要通过Application对象的WorksheetFunction属性来使用它。所以完整的写法是Application. WorksheetFunction.Transpose(k),中间的WorksheetFunction可省略。现在可以解释这句代码了:把字典中所有的关键字赋给以B1单元格开始的单元格区域中。
返回一个数组,其中包含了一个 Dictionary 对象中的所有项目。
object.Items( )
其中 object 总是一个 Dictionary 对象的名称。
常用语句:
Dim d, t& &
& &Set d = CreateObject(&Scripting.Dictionary&)
& &d.Add &a&, &Athens&& &
& &d.Add &b&, &Belgrade&
& &d.Add &c&, &Cairo&
& &t=d.Items
& &[C1].Resize(d.Count,1)=Application.Transpose(t)
1、Dim d, t :声明变量,d见前例;t默认是可变型数据类型(Variant)。
2、t=d.Items :把字典中所有的关键字对应的项赋给变量t。得到的也是一个一维数组,下限为0,上限为d.Count-1。这是数组的默认形式。
3、[C1].Resize(d.Count,1)=Application.Transpose(t) :有了上面Keys方法的解释这句代码就不用多说了,就是把字典中所有的关键字对应的项赋给以C1单元格开始的单元格区域中。
Remove方法
Remove 方法从一个 Dictionary 对象中清除一个关键字,项目对。
object.Remove(key )
其中 object 总是一个 Dictionary 对象的名称。
必选项。key 与要从 Dictionary 对象中删除的关键字,项目对相关联。
如果所指定的关键字,项目对不存在,那么将导致一个错误。
常用语句:
& &Set d = CreateObject(&Scripting.Dictionary&)
& &d.Add &a&, &Athens&& &
& &d.Add &b&, &Belgrade&
& &d.Add &c&, &Cairo&
& &d.Remove(“b”)
1、d.Remove(“b”):清除字典中”b”关键字和与它对应的项。清除之后,现在字典里只有2个关键字了。
RemoveAll方法
RemoveAll 方法从一个 Dictionary 对象中清除所有的关键字,项目对。
object.RemoveAll( )
其中 object 总是一个 Dictionary 对象的名称。
常用语句:
& &Set d = CreateObject(&Scripting.Dictionary&)
& &d.Add &a&, &Athens&& &
& &d.Add &b&, &Belgrade&
& &d.Add &c&, &Cairo&
& &d.RemoveAll
1、d.RemoveAll:清除字典中所有的数据。也就是清空这字典,然后可以添加新的关键字和项,形成一本新字典。
字典对象的属性有4个:Count属性、Key属性、Item属性、CompareMode属性。
返回一个Dictionary 对象中的项目数。只读属性。
& && &&&object.Count
其中 object一个字典对象的名称。
常用语句:
Dim d,n%& &
& &Set d = CreateObject(&Scripting.Dictionary&)
& &d.Add &a&, &Athens&& &
& &d.Add &b&, &Belgrade&
& &d.Add &c&, &Cairo&
& &n = d.Count
1、Dim d, n% :声明变量,d见前例;n被声明为整型数据类型(Integer)。一般写法为Dim n As Integer 。 Integer 的类型声明字符为百分比号 (%)。
2、n = d.Count&&:把字典中所有的关键字的数量赋给变量n。本例得到的是3。
在 Dictionary 对象中设置一个 key。
object.Key(key) = newkey
必选项。总是一个字典 (Dictionary) 对象的名称。
必选项。被改变的 key 值。
必选项。替换所指定的 key 的新值。
如果在改变一个 key 时没有发现该 key,那么将创建一个新的 key 并且其相关联的 item 被设置为空。
常用语句:
& &Set d = CreateObject(&Scripting.Dictionary&)
& &d.Add &a&, &Athens&& &
& &d.Add &b&, &Belgrade&
& &d.Add &c&, &Cairo&
& &d.Key(&c&) = &d&
1、d.Key(&c&) = &d& :用新的关键字”d”来替换指定的关键字”c”,这时,字典中就没有关键字c了,只有关键字d了,与d对应的项是”Cairo”。
在一个 Dictionary 对象中设置或者返回所指定 key 的 item。对于集合则根据所指定的 key 返回一个 item。读/写。
object.Item(key)[ = newitem]
必选项。总是一个Dictionary 对象的名称。
必选项。与要被查找或添加的 item 相关联的 key。
可选项。仅适用于 Dictionary 对象;newitem 就是与所指定的 key 相关联的新值。
如果在改变一个 key 的时候没有找到该 item,那么将利用所指定的 newitem 创建一个新的 key。如果在试图返回一个已有项目的时候没有找到 key,那么将创建一个新的 key 且其相关的项目被设置为空。
常用语句:
& &Set d = CreateObject(&Scripting.Dictionary&)
& &d.Add &a&, &Athens&& &
& &d.Add &b&, &Belgrade&
& &d.Add &c&, &Cairo&
& &MsgBox&&d.Item(&c&)
1、d.Item(&c&) :获取指定的关键字”c”对应的项。
2、MsgBox& &:是一个VBA函数,用消息框显示。如果要详细了解MsgBox函数的,可参见我的另一篇文章“常用VBA函数精选合集”。
CompareMode属性
设置或者返回在 Dictionary 对象中进行字符串关键字比较时所使用的比较模式。
object.CompareMode[ = compare]
必选项。总是一个 Dictionary 对象的名称。
可选项。如果提供了此项,compare 就是一个代表比较模式的值。可以使用的值是 0 (二进制)、1 (文本), 2 (数据库)。
如果试图改变一个已经包含有数据的 Dictionary 对象的比较模式,那么将导致一个错误。
常用语句:
& &Set d = CreateObject(&Scripting.Dictionary&)
& &d.CompareMode = vbTextCompare
& &d.Add &a&, &Athens&& &
& &d.Add &b&, &Belgrade&
& &d.Add &c&, &Cairo&
& &d.Add & B &, & Baltimore&
1、d.CompareMode = vbTextCompare&&:设置字典的比较模式是文本,在这种比较模式下不区分关键字的大小写,即关键字”b”和”B”是一样的。vbTextCompare的值为1,所以上式也可写为 d.CompareMode =1 。如果设置为vbBinaryCompare(值为0),则执行二进制比较,即区分关键字的大小写,此种情况下关键字”b”和”B”被认为是不一样的。
2、d.Add & B &, & Baltimore& :添加一关键字”B”和对应于它的项”Baltimore”。由于前面已经设置了比较模式为文本模式,不区分关键字的大小写,即关键字”b”和”B”是一样的,此时发生错误添加失败,因为字典中已经存在”b”了,字典中的关键字是唯一的,不能添加重复的关键字。
[ 本帖最后由 蓝桥玄霜 于
19:55 编辑 ]
19:55 上传
点击文件名下载附件
1.12 MB, 下载次数: 40694
阅读权限100
在线时间 小时
实例1 普通常见的求不重复值问题
求多表的不重复值问题
实例1&&普通常见的求不重复值问题
一、问题的提出:
表格中人员有很多是重复的,要求编写一段代码,把重复的人员姓名以及重复的次数求出来,复制到另一个表格中。Sub cfz()
Dim i&, Myr&, Arr
Dim d, k, t
Set d = CreateObject(&Scripting.Dictionary&)
Myr = Sheet1.[a65536].End(xlUp).Row
Arr = Sheet1.Range(&a1:g& & Myr)
For i = 2 To UBound(Arr)
& & d(Arr(i, 3)) = d(Arr(i, 3)) + 1
Next
k = d.keys
t = d.items
Sheet2.Activate
[a2].Resize(d.Count, 1) = Application.Transpose(k)
[b2].Resize(d.Count, 1) = Application.Transpose(t)
[a1].Resize(1, 2) = Array(&姓名&, &重复个数&)
Set d = Nothing
End Sub
复制代码三、代码详解
1、Dim i&, Myr&, Arr :变量i和Myr声明为长整型变量。 也可以写为 Dim Myr As Long 。Long 的类型声明字符为(&)。Arr后面没有写明数据类型,默认就是可变型数据类型(Variant)。
2、Set d = CreateObject(&Scripting.Dictionary&):创建字典对象,并把字典对象赋给变量d。这是最常用的一句代码。所谓的“后期绑定”。用了这句代码就不用先引用c:\windows\system32\scrrun.dll了。
3、Myr = Sheet1.[a65536].End(xlUp).Row :把表1的A列最后一行不为空白的行数赋给变量Myr。这里用了Range对象的End属性,它有4个方向参数,此处的xlUp表示向上,它的值为3,所以也可写成End(3)。xlDown表示向下,它的值为4;xlToLeft表示向左,它的值为1;xlToRight表示向右,它的值为2。
4、Arr = Sheet1.Range(&a1:g& & Myr):把表1的A1到G列最后一行不为空白的 单元格区域的值赋给变量Arr。这样Arr就是个二维数组了,用数组替代单元格引用可对执行代码的速度提高很多很多。
5、For i = 2 To UBound(Arr) :For…Next循环结构,从2开始到数组的最大上界值之间循环。因为数组的第一行是表头。Ubound是VBA函数,返回数组的指定维数的最大可用上界。
6、d(Arr(i, 3)) = d(Arr(i, 3)) + 1 :Arr(i,3)在本例是姓名列,也就是关键字列,举个例子,假如Arr(i,3)=”张三”,这句代码的意思就是把关键字”张三”加入字典,d(key)等于关键字key对应的项,每出现一次这个关键字,它的项的值就增加1。起到了按关键字累加的作用,也正因为有这个作用,所以可使用字典来进行各种汇总统计。后面要讲的实例会充分的展现这个作用。
7、k=d.keys :把字典d中存在的所有的关键字赋给变量k。得到的是一个一维数组,下限为0,上限为d.Count-1。Keys是字典的方法,前面已经讲过了。
8、t=d.items :把字典d中存在的所有的关键字对应的项赋给变量t。得到的也是一个一维数组,下限为0,上限为d.Count-1。Items也是字典的方法,前面也已经讲过了。
9、Sheet2.Activate :激活表2。
10、[a2].Resize(d.Count, 1) = Application.Transpose(k) :把字典d中所有的关键字赋给以a2单元格开始的单元格区域中。详细的解释请见前面的keys方法一节。
11、[b2].Resize(d.Count, 1) = Application.Transpose(t) :把字典d中所有的关键字对应的项赋给以b2单元格开始的单元格区域中。
12、[a1].Resize(1, 2) = Array(&姓名&, &重复个数&) :Array是一个VBA函数,返回一个下界为0的一维数组。一维数组是水平排列的,所以赋值给水平的单元格区域不需要用转置函数了。这里作为表头一次性输入。
13、Set d = Nothing&&:释放字典内存。
实例2&&求多表的不重复值问题
一、问题的提出:
一工作簿里面有3张工作表上,每张表格的A列都是姓名列,所有这些姓名中有些是重复的,要求编写一段代码,在另一个工作表上显示不重复的姓名。
如图实例2-1所示。
图&&实例2-1&&
这个问题也很适合用字典来解决。代码如下:Sub bcfz()
Dim i&, Myr&, Arr
Dim d, k, t, Sht As Worksheet
Set d = CreateObject(&Scripting.Dictionary&)
For Each Sht In Sheets
& & If Sht.Name && &Sheet4& Then
& && &&&Myr = Sht.[a65536].End(xlUp).Row
& && &&&Arr = Sht.Range(&a2:a& & Myr)
& && &&&For i = 1 To UBound(Arr)
& && && && &d(Arr(i, 1)) = &&
& && &&&Next
& & End If
Next
k = d.keys
Sheet4.[a3].Resize(d.Count, 1) = Application.Transpose(k)
Set d = Nothing
End Sub
复制代码三、代码详解
1、For Each Sht In Sheets :For Each…Next循环结构,这种形式是VBA特有的,用于对对象的循环非常适用。意思是在所有的工作表中依次循环。
2、If Sht.Name && &Sheet4& Then :如果这个工作表的名字不等于”Sheet4”时执行下面的代码。
3、Myr = Sht.[a65536].End(xlUp).Row :求得这个工作表A列有数据的最后一行的行数,把它赋给变量Myr。这里用了长整型数据类型(Long),数据范围最大可到2,147,483,647,是为了避免数据很多的时候会超出整型数据类型(Integer)而出错,因为整型数据类型数据范围最大只到32,767。
4、Arr = Sht.Range(&a2:a& & Myr)&&:把A列数据赋给数组Arr。
5、For i = 1 To UBound(Arr) :For…Next循环结构,从1开始到数组的最大上限值之间循环。Ubound是VBA函数,返回数组的指定维数的最大值。
6、d(Arr(i, 1)) = “” :这句代码的意思就是把关键字Arr(i,1)加入字典,关键字对应的项为空,相当于字典中的这个关键字没有解释。和d.Add Arr(i,1), &&的效果相同,只是代码更简洁一些。
7、k=d.keys :把字典d中存在的所有的关键字赋给变量k。得到的是一个一维数组,下限为0,上限为d.Count-1。Keys是字典的方法,前面已经讲过了。
8、Sheet4.[a3] .Resize(d.Count, 1) = Application.Transpose(k) :把字典d中所有的关键字赋给表4以a3单元格开始的单元格区域中。
代码执行后如图实例2-2所示。
图&&实例2-2
[ 本帖最后由 蓝桥玄霜 于
11:11 编辑 ]
10:27 上传
点击文件名下载附件
194.03 KB, 下载次数: 7499
10:27 上传
点击文件名下载附件
228.3 KB, 下载次数: 9101
11:11 上传
点击文件名下载附件
281.47 KB, 下载次数: 6277
11:11 上传
点击文件名下载附件
11.46 KB, 下载次数: 6357
好东西,一定要好好研究下&
太强大了,真是厉害
阅读权限100
在线时间 小时
实例3 实例4
实例3&&A列中显示1 ~ 1000中被6除余1和余5 的数字
一、问题的提出:
有1、2、3…1000一千个数字,要求编写一段代码,在工作表的A列显示这些数被6除余1和余5的数字。Sub 余1余5()&&‘by:狼版主
Dim dic As Object, i As Long, arr
Set dic = CreateObject(&Scripting.Dictionary&)
For i = 1 To 1000
dic.Add i & IIf(Abs(i Mod 6 - 3) = 2, &@&, &&), &&
Next
arr = WorksheetFunction.Transpose(Filter(dic.keys, &@&))
[a1].Resize(UBound(arr), 1) = arr
[a:a].Replace &@&, &&
Set dic = Nothing
End Sub
复制代码三、代码详解
1、Dim dic As Object, i As Long, arr&&:也可把字典变量dic声明为对象(Object),i As Long是规范的写法,也可写成i& 。
2、dic.Add i & IIf(Abs(i Mod 6 - 3) = 2, &@&, &&), && :这句代码的内容比较多,用了两个VBA函数IIf和Abs,用了一个Mod运算符。i Mod 6就是每一个数除6的余数,题目中有两个要求:余1和与5,为了从1到1000都同时能满足这两个要求,所以用了Abs(i Mod 6 - 3) = 2 ,Abs是取绝对值函数。另一个VBA函数IIf是根据判断条件返回结果,和If…Then判断结果类似;IIf(Abs(i Mod 6 - 3) = 2, &@&, &&) 这段的意思是如果符合判断条件,返回”@”否则返回空””。 i & IIf(Abs(i Mod 6 - 3) = 2, &@&, &&)的意思是把这个数与”@”或者”””连起来作为关键字加入字典dic,关键字相对应的项为空。比如当i=1时,1是满足上述表达式的,就把”1@” 作为关键字加入字典dic;当i=2时,2不满足上述表达式,就把”2” 作为关键字加入字典dic,关键字相对应的项都为空。
3、arr = WorksheetFunction.Transpose(Filter(dic.keys, &@&)) :这句代码的内容分为3部分,第1部分是Filter(dic.keys, &@&) 其中的Filter是一个VBA函数,VBA函数就是可以直接在代码中使用的,我们平常使用的函数叫工作表函数,如Sum、Sumif、Transpose等等。Filter函数要求在一维数组中筛选出符合条件的另一个一维数组,式中的dic.keys正是一个一维数组。这里的筛选条件是”@”,也就是把字典关键字中含有@的关键字筛选出来组成一个新的一维数组,其下标从零开始。第2部分是用工作表函数Transpose转置这个新的一维数组,工作表函数的使用在前面keys方法一节已经说过了;第2部分是把转置以后的值赋给数组变量Arr。
呵呵,狼版主的代码是短了,我的解释却太长了。
4、[a1].Resize(UBound(arr), 1) = arr :把数组Arr赋给[a1]单元格开始的区域中。
5、[a:a].Replace &@&, &&&&:把A列中的所有的@都替换为空白,只剩下数字了。
实例4&&拆分数据不重复
一、问题的提出:
有一列各种手机品牌型号的数据,要求编写一段代码,按照品牌划分成没有重复数据的三大类。
二、代码:Sub caifen()
Dim Myr&, Arr, x&
Dim d, d1, d2, i&, j&
Set d = CreateObject(&Scripting.Dictionary&)
Set d1 = CreateObject(&Scripting.Dictionary&)
Set d2 = CreateObject(&Scripting.Dictionary&)
Myr = [a65536].End(xlUp).Row
Arr = Range(&a2:a& & Myr)
Range(&c2:e& & Myr).ClearContents
my = Array(&MOTO&, &诺基亚&, &三星&, &索爱&)
gc = Array(&OPPO&, &联想&, &天语&, &金立&, &步步高&, &波导&, &TCL&, &酷派&)
For x = 1 To UBound(Arr)
& & For i = 0 To UBound(my)
& && &&&If InStr(Arr(x, 1), my(i)) & 0 Then
& && && && &d(Arr(x, 1)) = &&
& && && && &GoTo 100
& && &&&End If
& & Next i
& & For j = 0 To UBound(gc)
& && &&&If InStr(Arr(x, 1), gc(j)) & 0 Then
& && && && &d1(Arr(x, 1)) = &&
& && && && &GoTo 100
& && &&&End If
& & Next j
& & d2(Arr(x, 1)) = &&
100:
Next x
Range(&c2&).Resize(UBound(d.keys) + 1, 1) = Application.Transpose(d.keys)
Range(&d2&).Resize(UBound(d1.keys) + 1, 1) = Application.Transpose(d1.keys)
Range(&e2&).Resize(UBound(d2.keys) + 1, 1) = Application.Transpose(d2.keys)
End Sub& & & &&&
复制代码三、代码详解
1、Set d2 = CreateObject(&Scripting.Dictionary&)&&:针对三个不同的种类,创建d、d1、d2三个字典对象。
2、Myr = [a65536].End(xlUp).Row&&:把A列最后一行不为空白的行数赋给变量Myr。
3、Arr = Range(&a2:a& & Myr)&&:把A2开始的有数据的单元格区域赋给变量Arr。
4、Range(&c2:e& & Myr).ClearContents :把C2到E列单元格区域清空。
5、my = Array(&MOTO&, &诺基亚&, &三星&, &索爱&) :VBA函数Array返回一个一维数组,默认下界为0。把Array函数返回的数组赋给变量my(贸易两汉字的首字母)。
6、gc = Array(&OPPO&, &联想&, &天语&, &金立&, &步步高&, &波导&, &TCL&, &酷派&) :把Array函数返回的数组赋给变量gc(国产两汉字的首字母)。
7、For x = 1 To UBound(Arr) :在A列原始数据的数组中逐一循环。
8、For i = 0 To UBound(my) :在my数组中逐一循环。因为有4个贸易机品牌,所以用循环每一个与原始数据比较。
9、If InStr(Arr(x, 1), my(i)) & 0 Then :VBA函数Instr返回在第1个参数中查找的位置,如果返回结果=0,表示在第1个参数中没有第2个参数存在。本句的意思是如果找到贸易机品牌的话,执行下面的代码。
10、d1(Arr(x, 1)) = && :接上句,如果上面判断成立,就把Arr(x, 1)加入字典d。
11、GoTo 100 :Goto语句用于无条件地转移到过程中指定的行。这里采用跳出For i循环,一是为了减少循环的次数,比如&MOTO&找到的话,后面3个就不需要找了;二是为了跳过两个小循环之后的其它品牌加入第3个字典的d2(Arr(x, 1)) = &&语句。
12、For j循环与上面相同,为了判断得到国产机类的字典d1。
13、d2(Arr(x, 1)) = && :如果上述两个小循环都不满足,那么就加入其它品牌类字典里。
14、Range(&c2&).Resize(UBound(d.keys) + 1, 1) = Application.Transpose(d.keys) :最后的3句分别把字典的关键字数组转置后赋给相应的单元格区域。
山菊花版主用了一个字典对象就解决了上述问题。让我们来学习一下。
四、山菊花版主的代码:Sub 拆分()
& & Dim pp1$, pp2$, nRow%, ds, Brr(), s(1 To 3) As Integer
& & Set ds = CreateObject(&scripting.dictionary&)
& & pp1 = Join(WorksheetFunction.Transpose(Range(Range(&g2&), Range(&g1&).End(xlDown))), &,&)
& & pp2 = Join(WorksheetFunction.Transpose(Range(Range(&h2&), Range(&h1&).End(xlDown))), &,&)
& & nRow = Range(&a1&).End(xlDown).Row
& & Arr = Range(&a1:a& & nRow)
& & ReDim Brr(1 To nRow, 1 To 3)
& & For i = 2 To nRow
& && &&&If Not ds.Exists(Arr(i, 1)) Then
& && && && &ds(Arr(i, 1)) = &&
& && && && &If pp1 Like &*& & Left(Arr(i, 1), 2) & &*& Then
& && && && && & s(1) = s(1) + 1
& && && && && & Brr(s(1), 1) = Arr(i, 1)
& && && && &ElseIf pp2 Like &*& & Left(Arr(i, 1), 2) & &*& Then
& && && && && & s(2) = s(2) + 1
& && && && && & Brr(s(2), 2) = Arr(i, 1)
& && && && &Else
& && && && && & s(3) = s(3) + 1
& && && && && & Brr(s(3), 3) = Arr(i, 1)
& && && && &End If
& && &&&End If
& & Next
& & Range(&c2:e& & nRow) = Brr
End Sub& & & &
复制代码五、代码详解
1、pp1 = Join(WorksheetFunction.Transpose(Range(Range(&g2&), _
Range(&g1&).End(xlDown))), &,&) :
这句代码用了两个VBA函数Join 和Transpose ,Range(&g1&).End(xlDown)从G1单元格往下直到最下面的单元格,遇到空白格就停止。因为本例的G14、G15单元格有 另外的数据存在,如果还是用Range(&g65536&).End(xlUp),那么就会把不需要的数据带进去,造成结果出错。Transpose 转置函数,前面已经介绍过了。Join函数是通过连接某个数组中的多个子字符串而创建的一个字符串,本句代码执行后得到pp1=&MOTO, 诺基亚, 三星, 索爱&。
pp2一句同上句一样,得到另一个字符串。
2、nRow = Range(&a1&).End(xlDown).Row& &:把A列最后一行不为空白的行数赋给整型变量nRow。
3、Arr = Range(&a1:a& & nRow) :把A列A1开始的有数据的单元格区域赋给变量Arr。
4、ReDim Brr(1 To nRow, 1 To 3) :用于为动态数组变量Brr重新分配存储空间。第一维的下界从1到上界nRow,第二维从1到3。
5、For i = 2 To nRow :从2到 nRow逐一循环。
6、If Not ds.Exists(Arr(i, 1)) Then :如果字典ds中不存在关键字Arr(i, 1)
7、ds(Arr(i, 1)) = && :把Arr(i, 1)作为关键字加入字典ds。
8、If pp1 Like &*& & Left(Arr(i, 1), 2) & &*& Then :这里山版主用了比较运算符Like来比较pp1和取自Arr(i, 1)左边两个字符,再在前后加任意字符组成的字符串,如果满足条件为真,那么执行下面的语句。
9、s(1) = s(1) + 1 :数组s的第一个元素+1以后赋给数组s的第一个元素。
10、Brr(s(1), 1) = Arr(i, 1) :把这个关键字赋给第2维为1的另一个数组Brr,也就是我们要求的贸易机类。pp1字符串里都是贸易机类的品牌。
11、ElseIf pp2 Like &*& & Left(Arr(i, 1), 2) & &*& Then :同样,如果满足国产品牌类这个条件,那么执行下面的代码。
12、s(2) = s(2) + 1 :数组s的第二个元素+1以后赋给数组s的第二个元素。
13、Brr(s(2), 2) = Arr(i, 1) :把这个关键字赋给第2维为2的另一个数组Brr,也就是我们要求的国产品牌类。pp2字符串里都是国产品牌类的品牌。
14、s(3) = s(3) + 1 :前如果条件都不满足时,数组s的第三个元素+1以后赋给数组s的第三个元素。
15、Brr(s(3), 3) = Arr(i, 1) :把这个关键字赋给第3维为1的另一个数组Brr,也就是我们要求的其它品牌类。
16、Range(&c2:e& & nRow) = Brr :把数组Brr赋给[c2]单元格开始的区域中。
[ 本帖最后由 蓝桥玄霜 于
10:24 编辑 ]
10:24 上传
点击文件名下载附件
410.34 KB, 下载次数: 5870
10:24 上传
点击文件名下载附件
27.84 KB, 下载次数: 5735
真是把数组跟字典完美的结合在一起了
阅读权限100
在线时间 小时
实例5 实例6
[/code]实例5&&前期绑定的字典实例
一、问题的提出:
有多列多行数据,其中有重复的行,要求编写一段代码,求得不重复的行数据。
如图实例5-1所示。[code]Sub 保留原数据()&&‘by:ldy888
‘前期绑定,需先引用c:\windows\system32\scrrun.dll
& & Dim d As New Dictionary,t
& & For i = 2 To 5
& && &&&Set d(Cells(i, 1) & &&) = Range(Cells(i, 1), Cells(i, 4))
t=d.items& & & &
[A11].Resize(d.Count, 4) = Application.Transpose(Application.Transpose(t))
[/code]三、代码详解
1、Dim d As New Dictionary, t&&:本段代码需要先引用微软的脚本运行时库Microsoft Scripting Runtime,可在VBE窗口,从菜单-工具-引用,然后勾选Microsoft Scripting Runtime,或者点击浏览,在添加引用对话框中选择c:\windows\system32\scrrun.dll,并打开,确定。完成引用。在本声明语句中把字典d声明为New Dictionary。这就是”前期绑定”了。上面的实例用的是创建对象语句:
Set d = CreateObject(&Scripting.Dictionary&),称为”后期绑定”。不需要先引用脚本运行时库。
2、Set d(Cells(i, 1) & &&) = Range(Cells(i, 1), Cells(i, 4)) :把单元格对象加入字典,它对应的项是同一行的单元格区域。注意,这里用了Set,和前面的几例不一样哦。如果用Typename(d(Cells(i, 1) & &&)),得到的是一个Range对象。这里的Cells(i, 1) & &&也可以用Cells(i, 1).Value来代替。
3、t=d.items& &:把字典d中存在的所有的关键字对应的项赋给变量t。得到的是一个一维数组,下限为0,上限为d.Count-1。
4、[A11].Resize(d.Count, 4) = Application.Transpose(Application.Transpose(t)) :这句用了两次工作表转置函数Transpose之后赋给A11单元格开始的区域中。
代码执行后如图实例5-2所示。
实例6&&多条件复杂汇总
一、问题的提出:
有一个表格,需要对其中多个条件相同的数量进行合并汇总,并且要有汇总的明细数据,要求编写一段代码,实现这样的合并同类项的要求。
二、代码:[code]Sub kf2()&&‘by:oobird
Dim d As Object, a, b, j%, w!
Dim ss$, n%, x
Me.UsedRange.Offset(3, 0) = &&
a = Sheet1.Range(Sheet1.[a4], Sheet1.[i65536].End(xlUp))
Set d = CreateObject(&scripting.dictionary&)
ReDim b(1 To UBound(a), 1 To 8)
For i = 1 To UBound(a)
ss = a(i, 1) & a(i, 2) & a(i, 4) & a(i, 5) & a(i, 6) & a(i, 8)
If Not d.Exists(ss) Then
d.Add ss, n
b(n, 1) = a(i, 2): b(n, 2) = a(i, 5): b(n, 3) = a(i, 6): b(n, 4) = a(i, 4)
b(n, 5) = a(i, 1): b(n, 6) = a(i, 8): b(n, 7) = a(i, 9)
b(d(ss), 7) = b(d(ss), 7) & &+& & a(i, 9)
For i = 1 To d.Count
x = Split(b(i, 7), &+&)
For j = 0 To UBound(x)
w = w + x(j)
b(i, 8) = b(i, 5) * b(i, 6) * w / 100: w = 0
[b4].Resize(n, 8) = b
End Sub& & & &
[/code]三、代码详解
1、Dim d As Object, a, b, j%, w! :Dim语句中的j% 等同于Dim j As Integer。w! 等同于Dim w As Single。类似的还有ss$ 等同于Dim ss As String。还有双精度数据类型Double的类型声明字符为#、货币数据类型Currency的类型声明字符为@。
2、Me.UsedRange.Offset(3, 0) = && :Offset是Range对象的属性,Offset(3, 0)的第一个参数是行数;第二个参数是列数,意思是往下偏移3行,列不变。Me是活动工作表,相当于A UsedRange为已经使用的单元格区域。本句可解释为:清空第3行以下的单元格。
3、a = Sheet1.Range(Sheet1.[a4], Sheet1.[i65536].End(xlUp)) :把原始数据所在的表1自A4以下的I列最后的非空单元格区域的值赋给变量a。
4、Set d = CreateObject(&scripting.dictionary&) :创建字典对象d。
5、ReDim b(1 To UBound(a), 1 To 8) :根据数组a的大小重新声明数组b。
6、For i = 1 To UBound(a) :在1 和数组a第一维的上界值之间逐一循环。
7、ss = a(i, 1) & a(i, 2) & a(i, 4) & a(i, 5) & a(i, 6) & a(i, 8) :把多个条件比例、位置、项目名称、大系统编号、小系统编号和相同楼层数用连接符号&连成一个字符串,然后赋给变量ss。
8、If Not d.Exists(ss) Then :If…Then结构利用了字典的Exists方法和Not来判断:如果字典d里面不存在ss表示的关键字,那么执行下面的语句。
9、n = n + 1 :把变量n增加1以后仍然赋给n。
10、d.Add ss, n :把ss的值作为关键字,n的值作为对应的项一起加入字典d中。n的值实际是关键字的位置次序,如n=1时是第一个关键字;n=2时是第二个关键字。
11、b(n, 1) = a(i, 2): b(n, 2) = a(i, 5): b(n, 3) = a(i, 6): b(n, 4) = a(i, 4) :为了使代码看起来简短一些,可以用冒号”:”把多个语句连成一行。4个语句分别给数组b的各个元素赋以对应的值。
12、b(n, 5) = a(i, 1): b(n, 6) = a(i, 8): b(n, 7) = a(i, 9) :与上述的11条相同。
13、否则执行这句:b(d(ss), 7) = b(d(ss), 7) & &+& & a(i, 9) :d(ss)等于关键字对应的项,在本例里等于对应的n的值。本句是把图纸长度a(i, 9)用&+&连起来赋给数组b,这样就得到了长度明细一栏数据。
14、For i = 1 To d.Count :在字典关键字数目中逐一循环。
15、x = Split(b(i, 7), &+&) :运用VBA函数Split把b(i, 7)(长度明细)按照&+&分割,返回一个下标从零开始的一维数组x。如果要详细了解Split函数的,可参见我的另一篇文章“常用VBA函数精选合集”。
16、For j = 0 To UBound(x) :在上面的x数组之间逐一循环。
17、w = w + x(j) :把变量w加x(j)数组的一个元素以后仍然赋给w。实际得到x数组的累加值。
18、b(i, 8) = b(i, 5) * b(i, 6) * w / 100: w = 0 :w求出后经过按要求计算得到的值赋给数组b的第8列元素。(数量列)另一句把变量w置0。避免在新一次的循环中误加进去。
19、[b4].Resize(n, 8) = b :最后把数组b赋给B4开始的单元格区域。
代码执行后如图实例6-1所示。
[ 本帖最后由 蓝桥玄霜 于
10:04 编辑 ]
10:04 上传
点击文件名下载附件
563.11 KB, 下载次数: 6448
10:04 上传
点击文件名下载附件
70.1 KB, 下载次数: 6419
阅读权限100
在线时间 小时
实例7 实例8
实例7&&字典法排序
一、问题的提出:
A列B列是按顺序排列的全部股票代码和股票名称,C列D列和E列F列是另外按条件筛选出来的无序的数据, 要求编写一段代码,将它们排列到与A列相同的股票行里面。
二、代码:Private Sub CommandButton1_Click()&&‘by:oobird
Dim d As Object, rng, i%, j%, arr
Set d = CreateObject(&Scripting.Dictionary&)
rng = Range(&a3:f& & [a65536].End(xlUp).Row)
ReDim arr(1 To UBound(rng), 1 To 4)
For i = 1 To UBound(rng)& &
d(CStr(rng(i, 1))) = i
Next i
For j = 3 To 5 Step 2
For i = 1 To Cells(65536, j).End(xlUp).Row - 2
If d(CStr(rng(i, j))) && && Then
arr(d(CStr(rng(i, j))), j - 2) = rng(i, j)& &&&
arr(d(CStr(rng(i, j))), j - 1) = rng(i, j + 1)
End If
Next i
Next j
[c3].Resize(UBound(rng), 4) = arr
End Sub& & & &
复制代码三、代码详解
1、Dim d As Object, rng, i%, j%, arr :声明各个变量。
2、Set d = CreateObject(&Scripting.Dictionary&) :创建字典对象d。
3、rng = Range(&a3:f& & [a65536].End(xlUp).Row)&&:把A列到F列的单元格区域的值赋给变量rng。
4、ReDim arr(1 To UBound(rng), 1 To 4) :根据数组rng的大小重新声明动态数组变量的大小,这里是按最大数量来声明,可避免因声明得小了而导致代码出错。
5、For i = 1 To UBound(rng) :在rng数组中逐一循环。
6、d(CStr(rng(i, 1))) = i :把A列的股票代码的值用VBA转换函数CStr转换成字符串以后作为关键字,因为如果不作处理有时候遇到00开始的数据,可能会失去前面的0。股票代码在数组中的行位置i作为关键字对应的项,一起加入字典d。
7、For j = 3 To 5 Step 2 :前面的循环得到了整个字典,下面这两个循环用来与字典中的关键字比对而重新排位。Step 2是循环的步长,j=3执行以后,j=3+2=5,从而跳过j=4了。呵呵,这是For…Next循环结构的基础知识,说多了。
8、For i = 1 To Cells(65536, j).End(xlUp).Row – 2 :因为C列和E列的最后一个非空单元格的位置不一样,所以用了Cells(65536, j).End(xlUp).Row在循环中分别得到这两列的最后一个非空单元格的行数,由于数组rng是从第3行开始的,为了与下面引用的rng数组对应,所以需要减去2。全句是在C列和E列中逐一循环。
9、If d(CStr(rng(i, j))) && && Then :rng(i, j)是C列或者E列的股票代码,本句是如果这个股票代码关键字对应的项不等于空的时候,执行下面的代码。
10、arr(d(CStr(rng(i, j))), j - 2) = rng(i, j) :d(CStr(rng(i, j)))=i见上述6的解释,表示数组arr的第1维,相当于行;j-2是随着j=3的时候,j-2=1;j=5的时候j-2=3,相当于数组列的参数。把相应的股票代码赋给相同股票代码的第1列或者是第3列。
11、arr(d(CStr(rng(i, j))), j - 1) = rng(i, j + 1) :把相应的股票名称赋给相同股票代码的第2列或者是第4列。
12、[c3].Resize(UBound(rng), 4) = arr :把数组arr赋给C3开始的单元格区域。
代码执行后如图实例7-2所示。
实例8&&2级动态数据有效性问题
一、问题的提出:
A列是源名称,中间有空格,B列为各个源名称对应的数目不同的代号,C列是目标名称来源于源名称,要求在C列设置不重复的、没有空格的数据有效性供选择;同时D列目标代号,要求随着C列选择的目标名称的不同,提供对应的代号供选择,是为第2级数据有效性。
代码执行前如图实例8-1所示。
二、代码:Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Count & 1 Then Exit Sub
If Target.Column && 4 And Target.Column && 3 Then Exit Sub
Dim d, i&, Myr&, Arr, r%, Arr1(), cp$, ks&, js&, j&
Set d = CreateObject(&Scripting.Dictionary&)
Myr =[b65536].End(xlUp).Row
Arr = Range(&a2:b& & Myr)
If Target.Column = 3 Then
& & For i = 1 To UBound(Arr)
& && &&&If Arr(i, 1) && && Then
& && && && &d(Arr(i, 1)) = &&
& && &&&End If
& & Next
& & With Target.Validation
& && &&&.Delete
& && &&&.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
& && &&&Operator:=xlBetween, Formula1:=Join(d.keys, &,&)
& & End With
& & Target.Offset(0, 1) = &&
ElseIf Target.Column = 4 And Target.Offset(0, -1) && && Then
& & For i = 1 To UBound(Arr)
& && &&&If Arr(i, 1) && && Then
& && && && &r = r + 1
& && && && &ReDim Preserve Arr1(1 To r)
& && && && &Arr1(r) = i
& && &&&End If
& & Next i
& & For i = 1 To r
& && &&&If Arr(Arr1(i), 1) = Target.Offset(0, -1).Text Then
& && && && &If i && r Then
& && && && && & js = Arr1(i + 1) - 1
& && && && &Else
& && && && && & js = Myr - 1
& && && && &End If
& && && && &ks = Arr1(i)
& && && && &For j = ks To js
& && && && && & cp = cp & Arr(j, 2) & &,&
& && && && &Next
& && &&&End If
& & Next i
& & cp = Left(cp, Len(cp) - 1)
& & With Target.Validation
& && &&&.Delete
& && &&&.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
& && &&&Operator:=xlBetween, Formula1:=cp
& & End With
& & Target = Split(cp, &,&)(0)
End If
Set d = Nothing
End Sub
复制代码三、代码详解
1、Private Sub Worksheet_SelectionChange(ByVal Target As Range) :本例用的是工作表选择变化事件,只要鼠标点击单元格都会激活这个事件。Private 可译为私有的,限制了这段代码只能在指定的工作表里有效。参数Target声明为单元格区域对象,有了关键字ByVal,说明可以按值传递参数。
2、If Target.Count & 1 Then Exit Sub&&:由于是鼠标点击单元格都会激活这个事件,所以最好要作一些限制,使得你能避免点击了不需要激活事件的地方而激活本事件产生错误。本句是如果目标单元格的数目大于1就退出本过程。这样当你点选了多个单元格的时候,过程运行了这句代码就会结束过程了。
3、If Target.Column && 4 And Target.Column && 3 Then Exit Sub&&:再加一个限制,如果目标单元格的列不是3列(C列)也不是4列(D列)的话就退出过程。
4、接着的四句代码分别是声明变量、创建字典对象、B列最后一个非空单元格的行数以及把单元格区域的值赋给数组变量等等与前面的实例相同。请注意这里选择了B列求最后一个非空单元格的行数,是因为A列各数据之间有空格,如果选择A列,就会遗漏一些数据。
5、If Target.Column = 3 Then :现在分两种情况判断,如果点击的目标单元格是C列的,那么执行下面的代码。
6、If Arr(i, 1) && && Then :在数组Arr之间逐一循环,如果A列数组的值不等于空,就作为关键字加入字典d。这样就排除了空值进入字典。
7、With Target.Validation :这里使用了With语句,With语句为我们提供了十分简便的对象引用手段。使用它有3个优点:可以减少代码的输入量、增加代码的可读性。改善代码的执行效率。在End With之前的语句都是对目标单元格的有效性对象的各个属性进行设置。
8、.Delete :先删除该单元格的数据有效性。注意Delete前有个小圆点,在小圆点之前就省略了Target.Validation,即减少了代码的输入量。这个小圆点不能遗漏,否则会出错。
9、.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, Formula1:=Join(d.keys, &,&) :Add是有效性对象的方法,向指定区域内添加数据有效性检验。参数Type是数据有效性类型,当类型等于xlValidateList时,后面的公式1参数Formula1 必须包含以逗号分隔的取值列表。参数AlertStyle是出错警告样式,这里是停止样式;参数Operator是数据有效性运算符,有大于、小于、大于或等于、小于或等于、介于、不介于、等于、不等于等等,这里取介于;公式1参数Formula1的值用了VBA函数Join,把字典的关键字用逗号分隔后连接起来赋给公式1参数。这样,目标单元格那的数据有效性中就没有重复值了。
10、Target.Offset(0, 1) = && :给目标单元格设置了数据有效性以后,把它同行D列单元格的值清除。这是为了确保D列的值只与C列的目标名称相对应。
11、ElseIf Target.Column = 4 And Target.Offset(0, -1) && && Then :否则如果目标单元格是D列的,并且同行C列单元格不是空的情况下,执行这下面的代码。Offset属性的详解可见前面实例6的第2条解释。
12、For i = 1 To UBound(Arr) :在数组Arr之间逐一循环。
13、If Arr(i, 1) && && Then :如果A列数组的值不等于空,就执行下面的代码。
14、r = r + 1 :变量r累加。
15、ReDim Preserve Arr1(1 To r) :重新声明动态数组的大小,Preserve是关键字,当改变原有数组最末维的大小时,使用此关键字可以保持数组中原来的数据。这句是改变动态数组大小的最常用语句,不能忘记Preserve关键字。
16、Arr1(r) = i :把关键字在数组Arr中行的位置赋给新的动态数组Arr1(r)。这个循环可求得A列每一个源名称所在的行的位置。
17、For i = 1 To r :上面的循环求得了一共有r个源名称,逐一循环。
18、If Arr(Arr1(i), 1) = Target.Offset(0, -1).Text Then :如果C列的目标名称等于源名称时执行下面的代码。
19、If i && r Then :如果i不等于r时执行下面的代码。
20、js = Arr1(i + 1) – 1 :把下一个源名称所在的行数-1以后赋给变量js,这样来求得每一个源名称的开始和结束的位置。
21、js = Myr – 1 :否则就是最后一行-1的只赋给变量js(最后一个源名称在数组中的位置)。
22、ks = Arr1(i) :把数组的值赋给变量ks:得到每一个源名称的起始位置。
23、For j = ks To js :从每一个源名称的起始位置到结束位置逐一循环。
24、cp = cp & Arr(j, 2) & &,& :把相应的代号与逗号连接起来组成的字符串赋给变量cp。
25、cp = Left(cp, Len(cp) - 1) :用了两个VBA函数Left和Len把去掉末位的逗号。
26、With 语句解释同上,为D列单元格设置了第2级数据有效性。
27、Target = Split(cp, &,&)(0) :按照问题的第3个要求,在目标名称确定后,在目标代号相应位置自动生成目标名称的第一个代号。因为Split得到的是一个以0为下界的一维函数,所以它的第一个元素就用(0)来表示。
代码执行后如图实例8-2所示。
[ 本帖最后由 蓝桥玄霜 于
21:29 编辑 ]
21:29 上传
点击文件名下载附件
765.48 KB, 下载次数: 15358
21:29 上传
点击文件名下载附件
75.34 KB, 下载次数: 5332
阅读权限100
在线时间 小时
& & & & & & & &
实例9 实例10
实例9&&字典取行数,数组重新赋值
一、问题的提出:
要求编写一段代码,求得B列不重复的名字,其相应的A列和D列分别用& &连起来,而相应的E列F列的数值分别相加汇总。
代码执行前如图实例8-1所示。
二、代码:Sub yy()&&'by:Zamyi
Dim d As New Dictionary, R
Dim k, i&, j&
R = Sheet1.UsedRange
k = 1
For i = 2 To UBound(R)
& & R(i, 2) = Replace(Replace(R(i, 2), &(&, &(&), &)&, &)&)
& & If d.Exists(R(i, 2)) Then
& && &&&R(d(R(i, 2)), 1) = R(d(R(i, 2)), 1) & & & & R(i, 1)
& && &&&R(d(R(i, 2)), 4) = R(d(R(i, 2)), 4) & & & & R(i, 4)
& && &&&R(d(R(i, 2)), 5) = Val(R(d(R(i, 2)), 5)) + R(i, 5)
& && &&&R(d(R(i, 2)), 6) = Val(R(d(R(i, 2)), 6)) + R(i, 6)
& & Else
& && &&&k = k + 1
& && &&&d(R(i, 2)) = i
& && &&&For j = 1 To UBound(R, 2)
& && && && &R(k, j) = R(i, j)
& && &&&Next
&&End If
Next
With Sheet2
& & .Cells.ClearContents
& & .Cells.Borders.LineStyle = xlNone
& & .[a1:F1].Resize(d.Count + 1) = R
& & .[a1:F1].Resize(d.Count + 1).Borders.LineStyle = 1
End With
Set d = Nothing
End Sub& & & &
复制代码三、代码详解
1、R = Sheet1.UsedRange :把表1的已经使用了的单元格区域的值赋给变量R。
2、k = 1 :变量k赋初值1。
3、For i = 2 To UBound(R)&&:由于第一行是表头,所以从第2行开始循环。
4、R(i, 2) = Replace(Replace(R(i, 2), &(&, &(&), &)&, &)&) :由于源数据中用了不统一的括号,所以加了这句把里面中文括号统一替换为英文括号。这句用了两次VBA函数Replace,一次替换前半个,另一次替换后半个。Replace函数有6个参数,详细请查阅VBA帮助文件。如果在这里解释,篇幅太长了,也冲淡了字典的主题。
5、If d.Exists(R(i, 2)) Then :这句用字典的Exists方法进行判断,如果字典中存在R(i, 2)这个关键字,那么执行下面的代码。
6、这里先解释,Else如果上面的判断不成立,即字典中不存在这个关键字时,要执行下面的代码。
7、k = k + 1 :变量k+1以后再赋给k。
8、d(R(i, 2)) = i :公司名字作为关键字,对应的项是它所在的行,把它们加入字典d。
9、For j = 1 To UBound(R, 2) :知道了这个关键字所在的行,下面这个循环就是重新给数组同一行的各个元素赋值。UBound(R, 2)是用VBA函数Ubound求得数组R的第2维的最大上界。比如本例R数组第1维的最大上界是8,有8行数据;而第2维的最大上界是6,有6列数据。本循环j就是从第1列到第6列依次循环。
10、R(k, j) = R(i, j) :把i行j列的数组元素赋给k行j列的R数组元素。
11、R(d(R(i, 2)), 1) = R(d(R(i, 2)), 1) & & & & R(i, 1) :再回来说如果R(i, 2)这个关键字存在,则执行这条代码。在这之前,这关键字已经加入字典了,它的同一行的各个数组元素也重新赋过值了,所以根据问题的要求,把A列的数据用& &连起来再赋给A列这个数组元素。
12、R(d(R(i, 2)), 4) = R(d(R(i, 2)), 4) & & & & R(i, 4) :D列数据同上。
13、R(d(R(i, 2)), 5) = Val(R(d(R(i, 2)), 5)) + R(i, 5) :E 列数据要相加,这里用了VBA函数Val,把E列数组元素转为数值以后相加汇总。下句类同。
14、With Sheet2 :With语句,前面介绍过的。
15、.Cells.ClearContents :清空表2所有的数据。Cells是工作表对象的属性,指工作表所有的单元格;ClearContents是它的方法,清除里面的公式、数据,但是保留格式设置。
16、.Cells.Borders.LineStyle = xlNone :清除表2所有的边框。Borders是Cells的属性,意思是单元格的边框;LineStyle是边框的属性,为边框的线型,它有直线、虚线、点划线等等,这里取值xlNone是清除边框。
17、.[a1:F1].Resize(d.Count + 1) = R :把数组R的值赋给表2A1单元格开始的区域。
18、.[a1:F1].Resize(d.Count + 1).Borders.LineStyle = 1 :给这些单元格添加边框,线型为直线。
代码执行后如图实例9-2所示。
实例10&&先字典求得行后显示整行数据
一、问题的提出:
有3列数据,要求编写一段代码,如果C列名次、A列主排相同时,根据B列次排最大的只保留一行。
解题思路:先对3列数据按主要关键字名次_升序,次要关键字主排_升序,第3关键字次排_降序进行排序,然后运用字典,以”名次|主排” 作为关键字,它所在的行作为关键字的项加入字典,最后根据行引用相对的单元格值。
代码执行前如图实例10-1所示。
二、代码:Sub pmc()
Dim i&, Myr&, Arr
Dim d, x, rng
Application.ScreenUpdating = False
Set d = CreateObject(&Scripting.Dictionary&)
Sheet1.Activate
Myr = [a65536].End(xlUp).Row
Range(&A1:C& & Myr).Sort Key1:=Range(&C2&), Order1:=xlAscending, Key2:=Range( _
& && &&&&A2&), Order2:=xlAscending, Key3:=Range(&B2&), Order3:=xlDescending, _
& && &&&Header:=xlYes
Arr = Range(&a2:c& & Myr)
For i = 1 To UBound(Arr)
& & x = Arr(i, 1) & &|& & Arr(i, 3)
& & If Not d.exists(x) Then
& && &&&d.Add x, i + 1
& & End If
Next
[e:g].ClearContents
[e2].Resize(d.Count, 1) = Application.Transpose(d.items)
For Each rng In [e2].Resize(d.Count, 1)
& & rng.Resize(1, 3) = Cells(rng, 1).Resize(1, 3).Value
Next
Set d = Nothing
Application.ScreenUpdating = True
End Sub
复制代码三、代码详解
1、Application.ScreenUpdating = False :关闭屏幕更新。关闭屏幕更新可加快宏的执行速度。请记住当宏结束执行时,将 ScreenUpdating 属性设回到 True。
2、Range(&A1:C& & Myr).Sort Key1:=Range(&C2&), Order1:=xlAscending, Key2:=Range(&A2&), Order2:=xlAscending, Key3:=Range(&B2&), Order3:=xlDescending, _
Header:=xlYes :对ABC三列进行排序。主要关键字Key1名次_升序,次要关键字Key2主排_升序,第3关键字Key3次排_降序。
3、Arr = Range(&a2:c& & Myr) :把ABC列数据赋给变量Arr。
4、For i = 1 To UBound(Arr)&&:i从1到数组Arr的最大上界逐一循环。
5、x = Arr(i, 1) & &|& & Arr(i, 3) :把主排和”|”和名次连起来赋给变量x。
6、If Not d.exists(x) Then :如果字典中不存在x这个关键字,那么执行下面的代码。
7、d.Add x, i + 1 :把x作为关键字和这个关键字的具体的行作为对应的项加入字典。因为数组Arr是从A2开始的,所以i与数据的实际行相差1,i+1就是数据的实际行。
8、[e:g].ClearContents :清空E~G列。
9、[e2].Resize(d.Count, 1) = Application.Transpose(d.items) :把字典所有的项转置以后赋给E2单元格开始的区域。
10、For Each rng In [e2].Resize(d.Count, 1) :For- Each-Next控制结构是VBA中功能最强的循环控制结构,利用这个结构可对集合中的所有对象或者数组中的所有元素进行同一操作。它的一个优点在于你不必操心循环应该执行多少次,它循环的次数恰好就是数组中元素的个数(或者集合中对象的个数),因此对于处理多维数组特别是处理对象时最有效率。本句意思是在E2单元格开始的单元格区域中逐一循环。
11、rng.Resize(1, 3) = Cells(rng, 1).Resize(1, 3).Value :把关键字所在行的3个单元格的值赋给rng开始的3个单元格。在Cells(rng, 1)中作为参数的rng=rng.Valur,而rng.Resize(1, 3)处的rng是一个单元格对象。
代码执行后如图实例10-2所示。
doc文件(全)请到1楼下载。
[ 本帖最后由 蓝桥玄霜 于
19:24 编辑 ]
19:24 上传
点击文件名下载附件
22.38 KB, 下载次数: 4916
阅读权限100
在线时间 小时
实例11 实例12
实例11&&关键字赋给两列后用Replace方法
一、问题的提出:
有如图实例11-1所示的工资表,要求编写一段代码,运用VBA自动生成1季度的工资表。
解题思路:先把性别和姓名连起来作为关键字求得人员的不重复值,然后通过循环查找关键字获得其各月的工资,最后用Replace方法替换两列关键字区域得到各自的数据。
代码执行前如图实例11-1所示。
二、代码:Sub yy()
Dim d, k, t, i&, j&, Arr, x, r1
Set d = CreateObject(&Scripting.Dictionary&)
Arr = [a1].CurrentRegion
For i = 1 To UBound(Arr, 2) Step 3
& & For j = 2 To UBound(Arr)
& && &&&If Arr(j, i) && && Then
& && && && & x = Arr(j, i) & &|& & Arr(j, i + 1)
& && && && & d(x) = &&
& && &&&End If
& & Next
Next
k = d.keys
[a12:i1000].ClearContents
[a13].Resize(d.Count, 2) = Application.Transpose(k)
[a12:b12] = Array(&性别&, &姓名&)
For i = 3 To UBound(Arr, 2) Step 3
& & Cells(12, 2 + i / 3) = Cells(1, i)
Next
For i = 3 To UBound(Arr, 2) Step 3
& & For j = 2 To UBound(Arr)
& && &&&If Arr(j, i) && && Then
& && && && &x = Arr(j, i - 2) & &|& & Arr(j, i - 1)
& && && && &Set r1 = [a13].Resize(d.Count, 1).Find(x, , , 1)
& && && && &Cells(r1.Row, 2 + i / 3) = Arr(j, i)
& && &&&End If
& & Next
Next
[a13].Resize(d.Count, 1).Replace &|*&, &&, xlPart
[b13].Resize(d.Count, 1).Replace &*|&, &&, xlPart
End Sub
复制代码三、代码详解
1、Arr = [a1].CurrentRegion :把含有A1单元格的当前单元格区域的值赋给变量Arr。CurrentRegion是Range对象的属性,当前区域指以任意空白行及空白列的组合为边界的区域。如本题A11单元格有数据,但是因为第10行是空白行,所以没有包含在A1的当前区域里面。
2、For i = 1 To UBound(Arr, 2) Step 3&&:For-Next控制结构,从1 到数组第2维的最大上界每隔3进行一次循环,Step 3是循环的步长,第一次循环时i=1;第2次循环时i=1+3=4,第3次时i=4+3=7。
3、For j = 2 To UBound(Arr)&&:从第2行开始循环。没有Step时默认Step为1。
4、If Arr(j, i) && && Then :If-Then-Else控制结构可根据测试条件的结果改变程序执行的流程。本句测试条件是Arr(j, i) && &&,判断性别是否为空白,如果不为空白则执行下面的语句,否则,执行Else下面的语句。
5、x = Arr(j, i) & &|& & Arr(j, i + 1) :把性别和姓名中间加“|”连起来赋给变量x。
6、d(x) = && :把x的值作为关键字加入字典d。比如把”男|赵” 加入字典d。这两个循环把每个月的所有的人员都加入了字典d,字典中的人员是没有重复的。
7、k = d.keys :把字典d所有的关键字赋给变量k。
8、[a12:i1000].ClearContents :清空A12:I1000单元格区域。
9、[a13].Resize(d.Count, 2) = Application.Transpose(k) :把变量k转置之后赋给A13开始的单元格区域。Resize是Range对象的属性,调整指定区域的大小,其第1个参数是行的大小,d.Count表示字典关键字的数量,如果有10个关键字,那么就是10行;其第2个参数是列的大小,一般是赋给1列的,本例关键字由两个数据合并而成,所以先赋给2列,后面再处理。
10、[a12:b12] = Array(&性别&, &姓名&) :Array是一个VBA函数,返回一个下界为0的一维数组。一维数组可以看作是水平排列的,这里作为表头一次性输入。
11、For i = 3 To UBound(Arr, 2) Step 3 :从第3列开始循环,步长为3。
12、Cells(12, 2 + i / 3) = Cells(1, i) :把“1月工资“、“2月工资“等输入到相应表头的位置。
13、Set r1 = [a13].Resize(d.Count, 1).Find(x, , , 1) :在A13单元格开始的区域中查找字符串变量x,Find方法是Range对象的一个方法,其中第4个参数值为1,其常量为xlWhole,表示精确查找,另一个常量为xlPart,它的值=2。Find方法返回的是Range对象,所以前面要用Set语句来引用对象。
14、Cells(r1.Row, 2 + i / 3) = Arr(j, i) :把关键字对应的工资赋给相应的单元格里。
15、[a13].Resize(d.Count, 1).Replace &|*&, &&, xlPart :Replace方法是Range对象的一个方法,其第1个参数是要查找的字符串,这里&|*&是竖线及后面所有的字符串;其第2个参数是替换字符串,这里替换为空;其第3个参数是精确查找还是模糊查找,xlPart常量的值=2,可以用2代替它。本句是把姓名替换掉,只留下性别;下一句把B列中的性别替换掉,只留下姓名。
代码执行后如图实例11-2所示。
实例12&&复杂报表汇总
一、问题的提出:
有一日报表,里面有生产型号、生产数量、返修原因、返修数量、报废原因、报废数量,要求编写一段代码,按同型号产品汇总生产数量;得到同型号产品相同返修原因的唯一值;按同型号产品相同返修原因汇总返修数量; 得到同型号产品相同报废原因的唯一值;同型号产品相同报废原因汇总报废数量,并且合并相同内容的单元格。
代码执行前如图实例12-1所示。
二、代码:Sub bbhz()
Dim i&, Myr&, x(1 To 3), Arr, n%, aa, j&, Arr1(), r%, Arr2(), r2%, r3%, Arr3()
Dim d(1 To 3) As New dictionary, k(1 To 3), t(1 To 3), js, ks, ii%, jj&, ks1, js1
Application.ScreenUpdating = False
Myr = Sheet1.[a65536].End(xlUp).Row
Arr = Sheet1.Range(&a3:g& & Myr)
For i = 1 To UBound(Arr)
& & x(1) = Arr(i, 2)
& & d(1)(x(1)) = d(1)(x(1)) + Arr(i, 3)
& & x(2) = Arr(i, 2) & &|& & Arr(i, 4)
& & d(2)(x(2)) = d(2)(x(2)) + Arr(i, 5)
& & x(3) = Arr(i, 2) & &|& & Arr(i, 4) & &|& & Arr(i, 6)
& & d(3)(x(3)) = d(3)(x(3)) + Arr(i, 7)
Next
For i = 1 To 3
& & k(i) = d(i).Keys
& & t(i) = d(i).Items
Next
Sheet4.Activate
[a3:k1000].ClearContents
[a3:k1000].UnMerge
[a3:k1000].Borders.LineStyle = xlNone
[i3].Resize(d(3).Count, 1) = Application.Transpose(t(3))
n = 2
For i = 0 To UBound(k(3))
& & aa = Split(k(3)(i), &|&)
& & n = n + 1
& & Cells(n, 2) = aa(0)
& & Cells(n, 4) = aa(1)
& & Cells(n, 8) = aa(2)
Next
For i = 3 To n
& & For j = 0 To UBound(k(1))
& && &&&If}

我要回帖

更多关于 浙江富豪pk广东富豪 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信