DataBase.pas 139 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769
  1. unit DataBase;
  2. interface
  3. uses
  4. SysUtils,
  5. Classes,
  6. DBClient,
  7. Provider,
  8. DB,
  9. ADODB,
  10. ScBillsTree,
  11. ConstVarUnit,
  12. ConstMethodUnit,
  13. ScKindsOfTrees,
  14. ConstTypeUnit,
  15. ZjIDTree,
  16. ScExprsDM,
  17. ZJLists;
  18. type
  19. // 评分统计,参数:附加费
  20. TStatEvent = procedure (AFJF: Currency; AYsCount, AQdCount: Integer) of object;
  21. // 评分部分用到,为了和SmartCost定义保持一致,方便代码Copy. chenshilong, 2011-07-20
  22. TStdItem = TStdBillNode;
  23. TStdTree = TStdBillsTree;
  24. TDMDataBase = class(TDataModule)
  25. atBills: TADOTable;
  26. atDrawingQuantity: TADOTable;
  27. dspBills: TDataSetProvider;
  28. dspDrawingQuantity: TDataSetProvider;
  29. cdsBills: TClientDataSet;
  30. cdsDrawingQuantity: TClientDataSet;
  31. dsBillsDrawing: TDataSource;
  32. cdsOrgBills: TClientDataSet;
  33. cdsOrgDrawingQuantity: TClientDataSet;
  34. cdsDrawingQuantityID: TIntegerField;
  35. cdsDrawingQuantityName: TWideStringField;
  36. cdsDrawingQuantityUnits: TWideStringField;
  37. cdsDrawingQuantityBillsID: TIntegerField;
  38. cdsDrawingQuantityDQuantity1: TFloatField;
  39. cdsDrawingQuantityDQuantity2: TFloatField;
  40. cdsBillsID: TIntegerField;
  41. cdsBillsParentID: TIntegerField;
  42. cdsBillsNextSiblingID: TIntegerField;
  43. cdsBillsCode: TWideStringField;
  44. cdsBillsName: TWideStringField;
  45. cdsBillsUnits: TWideStringField;
  46. cdsBillsQuantity: TFloatField;
  47. cdsBillsUnitPrice: TBCDField;
  48. cdsBillsTotalPrice: TBCDField;
  49. cdsBillsB_Code: TWideStringField;
  50. cdsBillsDesignQuantity: TFloatField;
  51. cdsBillsDesignQuantity2: TFloatField;
  52. cdsBillsDesignPrice: TFloatField;
  53. cdsBillsMemoStr: TMemoField;
  54. cdsOrgBillsID: TIntegerField;
  55. cdsOrgBillsParentID: TIntegerField;
  56. cdsOrgBillsNextSiblingID: TIntegerField;
  57. cdsOrgBillsCode: TWideStringField;
  58. cdsOrgBillsName: TWideStringField;
  59. cdsOrgBillsUnits: TWideStringField;
  60. cdsOrgBillsQuantity: TFloatField;
  61. cdsOrgBillsUnitPrice: TBCDField;
  62. cdsOrgBillsTotalPrice: TBCDField;
  63. cdsOrgBillsB_Code: TWideStringField;
  64. cdsOrgBillsDesignQuantity: TFloatField;
  65. cdsOrgBillsDesignQuantity2: TFloatField;
  66. cdsOrgBillsDesignPrice: TFloatField;
  67. cdsOrgBillsMemoStr: TMemoField;
  68. cdsOrgDrawingQuantityID: TIntegerField;
  69. cdsOrgDrawingQuantityName: TWideStringField;
  70. cdsOrgDrawingQuantityUnits: TWideStringField;
  71. cdsOrgDrawingQuantityBillsID: TIntegerField;
  72. cdsOrgDrawingQuantityDQuantity1: TFloatField;
  73. cdsBillsIsPreDefine: TBooleanField;
  74. cdsOrgBillsIsPreDefine: TBooleanField;
  75. cdsDrawingQuantityMemoContext: TWideStringField;
  76. cdsOrgDrawingQuantityMemoContext: TWideStringField;
  77. cdsDQForLocate: TClientDataSet;
  78. cdsDQForLocateID: TIntegerField;
  79. cdsDQForLocateBillsID: TIntegerField;
  80. cdsDQForLocateName: TWideStringField;
  81. cdsDQForLocateUnits: TWideStringField;
  82. cdsDQForLocateMemoContext: TWideStringField;
  83. cdsDQForLocateDQuantity1: TFloatField;
  84. cdsDQForLocateDQuantity2: TFloatField;
  85. cdsDrawingQuantitySerinalNo: TIntegerField;
  86. cdsOrgDrawingQuantitySerinalNo: TIntegerField;
  87. cdsDQForLocateSerinalNo: TIntegerField;
  88. cdsOrgBillsSelected: TBooleanField;
  89. cdsXMJBills: TClientDataSet;
  90. cdsOrgBillsOwnerName: TWideStringField;
  91. cdsXMJBillsQuantity: TFloatField;
  92. cdsXMJBillsUnitPrice: TBCDField;
  93. cdsXMJBillsTotalPrice: TBCDField;
  94. cdsXMJBillsDesignQuantity: TFloatField;
  95. cdsXMJBillsDesignQuantity2: TFloatField;
  96. cdsXMJBillsDesignPrice: TFloatField;
  97. cdsXMJBillsID: TIntegerField;
  98. cdsXMJBillsParentID: TIntegerField;
  99. cdsXMJBillsNextSiblingID: TIntegerField;
  100. cdsXMJBillsCode: TWideStringField;
  101. cdsXMJBillsName: TWideStringField;
  102. cdsXMJBillsUnits: TWideStringField;
  103. cdsXMJBillsB_Code: TWideStringField;
  104. cdsXMJBillsMemoStr: TMemoField;
  105. cdsXMJBillsSelected: TBooleanField;
  106. cdsXMJBillsIsPreDefine: TBooleanField;
  107. cdsBillsSelected: TBooleanField;
  108. cdsDQForLocateIsGatherQ: TBooleanField;
  109. cdsOrgDrawingQuantityIsGatherQ: TBooleanField;
  110. cdsDrawingQuantityIsGatherQ: TBooleanField;
  111. cdsOrgBillsCustomValue: TFloatField;
  112. cdsBillsCustomValue: TFloatField;
  113. cdsBillsSerialNo: TIntegerField;
  114. cdsOrgBillsSerialNo: TIntegerField;
  115. cdsBillsLookup: TClientDataSet;
  116. cdsBillsLookupID: TIntegerField;
  117. cdsBillsLookupParentID: TIntegerField;
  118. cdsBillsLookupNextSiblingID: TIntegerField;
  119. cdsBillsLookupCode: TWideStringField;
  120. cdsBillsLookupName: TWideStringField;
  121. cdsBillsLookupUnits: TWideStringField;
  122. cdsBillsLookupQuantity: TFloatField;
  123. cdsBillsLookupUnitPrice: TBCDField;
  124. cdsBillsLookupTotalPrice: TBCDField;
  125. cdsBillsLookupB_Code: TWideStringField;
  126. cdsBillsLookupDesignQuantity: TFloatField;
  127. cdsBillsLookupDesignQuantity2: TFloatField;
  128. cdsBillsLookupDesignPrice: TFloatField;
  129. cdsBillsLookupMemoStr: TMemoField;
  130. cdsBillsLookupIsPreDefine: TBooleanField;
  131. cdsBillsLookupSelected: TBooleanField;
  132. cdsBillsLookupCustomValue: TFloatField;
  133. cdsBillsLookupSerialNo: TIntegerField;
  134. cdsBillsErrorHint: TWideStringField;
  135. cdsBillsIsSuperscale: TBooleanField;
  136. cdsBillsStandardGrade: TFloatField;
  137. cdsBillsDeductGrade: TFloatField;
  138. cdsBillsIsIgNore: TBooleanField;
  139. cdsBillsUserModified: TBooleanField;
  140. cdsBillsLostPreSiblingCount: TIntegerField;
  141. cdsBillsLostChildrenCount: TIntegerField;
  142. cdsBillsLostNextSiblingCount: TIntegerField;
  143. cdsBillsNameErrorFlag: TIntegerField;
  144. cdsBillsUnitsErrorFlag: TIntegerField;
  145. cdsBillsLookupLostNextSiblingCount: TIntegerField;
  146. cdsBillsLookupLostChildrenCount: TIntegerField;
  147. cdsBillsLookupLostPreSiblingCount: TIntegerField;
  148. cdsBillsLookupUserModified: TBooleanField;
  149. cdsBillsLookupIsIgNore: TBooleanField;
  150. cdsBillsLookupDeductGrade: TFloatField;
  151. cdsBillsLookupStandardGrade: TFloatField;
  152. cdsBillsLookupIsSuperscale: TBooleanField;
  153. cdsBillsLookupErrorHint: TWideStringField;
  154. cdsBillsLookupNameErrorFlag: TIntegerField;
  155. cdsBillsLookupUnitsErrorFlag: TIntegerField;
  156. cdsOrgBillsLostNextSiblingCount: TIntegerField;
  157. cdsOrgBillsLostChildrenCount: TIntegerField;
  158. cdsOrgBillsLostPreSiblingCount: TIntegerField;
  159. cdsOrgBillsUserModified: TBooleanField;
  160. cdsOrgBillsIsIgNore: TBooleanField;
  161. cdsOrgBillsDeductGrade: TFloatField;
  162. cdsOrgBillsStandardGrade: TFloatField;
  163. cdsOrgBillsIsSuperscale: TBooleanField;
  164. cdsOrgBillsErrorHint: TWideStringField;
  165. cdsOrgBillsNameErrorFlag: TIntegerField;
  166. cdsOrgBillsUnitsErrorFlag: TIntegerField;
  167. aqStat: TADOQuery;
  168. aqStatChapterID: TIntegerField;
  169. aqStatCode: TWideStringField;
  170. aqStatName: TWideStringField;
  171. aqStatStandardGrade: TFloatField;
  172. aqStatDeductGrade: TFloatField;
  173. aqStatActureMark: TCurrencyField;
  174. aqStatTotalMark: TCurrencyField;
  175. aqStatResultMark: TCurrencyField;
  176. aqStatStdMarkPercent: TBCDField;
  177. aqStatYsCount: TIntegerField;
  178. aqStatQdCount: TIntegerField;
  179. cdsStat: TClientDataSet;
  180. cdsStatChapterID: TIntegerField;
  181. cdsStatCode: TWideStringField;
  182. cdsStatName: TWideStringField;
  183. cdsStatStandardGrade: TBCDField;
  184. cdsStatDeductGrade: TBCDField;
  185. cdsStatActureMark: TBCDField;
  186. cdsStatTotalMark: TBCDField;
  187. cdsStatResultMark: TBCDField;
  188. cdsStatStdMarkPercent: TBCDField;
  189. cdsStatYsCount: TIntegerField;
  190. cdsStatQdCount: TIntegerField;
  191. dsStat: TDataSource;
  192. atStat: TADOTable;
  193. dspStat: TDataSetProvider;
  194. cdsBillsChapterID: TIntegerField;
  195. cdsOrgBillsChapterID: TIntegerField;
  196. cdsXMJBillsLostNextSiblingCount: TIntegerField;
  197. cdsXMJBillsLostChildrenCount: TIntegerField;
  198. cdsXMJBillsLostPreSiblingCount: TIntegerField;
  199. cdsXMJBillsUserModified: TBooleanField;
  200. cdsXMJBillsIsIgNore: TBooleanField;
  201. cdsXMJBillsDeductGrade: TFloatField;
  202. cdsXMJBillsStandardGrade: TFloatField;
  203. cdsXMJBillsIsSuperscale: TBooleanField;
  204. cdsXMJBillsErrorHint: TWideStringField;
  205. cdsXMJBillsNameErrorFlag: TIntegerField;
  206. cdsXMJBillsUnitsErrorFlag: TIntegerField;
  207. cdsXMJBillsChapterID: TIntegerField;
  208. acProject: TADOConnection;
  209. cdsBillsFullCode: TWideStringField;
  210. cdsStatTotal: TClientDataSet;
  211. atStatTotal: TADOTable;
  212. dspStatTotal: TDataSetProvider;
  213. cdsStatTotalID: TIntegerField;
  214. cdsStatTotalStandardGradeTotal: TBCDField;
  215. cdsStatTotalDeductGradeTotal: TBCDField;
  216. cdsStatTotalResultMarkTotal: TBCDField;
  217. cdsStatTotalAdditionalMark: TBCDField;
  218. cdsStatTotalQualityMark: TBCDField;
  219. cdsStatTotalYsCountTotal: TIntegerField;
  220. cdsStatTotalQdCountTotal: TIntegerField;
  221. aqStatTotal: TADOQuery;
  222. aqStatTotalID: TIntegerField;
  223. aqStatTotalStandardGradeTotal: TBCDField;
  224. aqStatTotalDeductGradeTotal: TBCDField;
  225. aqStatTotalResultMarkTotal: TBCDField;
  226. aqStatTotalAdditionalMark: TBCDField;
  227. aqStatTotalQualityMark: TBCDField;
  228. aqStatTotalYsCountTotal: TIntegerField;
  229. aqStatTotalQdCountTotal: TIntegerField;
  230. cdsBillsRightName: TWideStringField;
  231. cdsBillsRightUnits: TWideStringField;
  232. cdsOrgBillsRightName: TWideStringField;
  233. cdsOrgBillsRightUnits: TWideStringField;
  234. cdsBillsIsLeaf: TBooleanField;
  235. cdsOrgBillsIsLeaf: TBooleanField;
  236. cdsXMJBillsRightName: TWideStringField;
  237. cdsXMJBillsRightUnits: TWideStringField;
  238. cdsBillsIsCreatePriceAnalysis: TBooleanField;
  239. cdsOrgBillsIsCreatePriceAnalysis: TBooleanField;
  240. cdsBillsB_CodeAlpha: TWideStringField;
  241. cdsBillsIsAccQuantity: TBooleanField;
  242. cdsBillsLookupIsAccQuantity: TBooleanField;
  243. cdsOrgBillsIsAccQuantity: TBooleanField;
  244. blnfldXMJBillsIsAccQuantity: TBooleanField;
  245. cdsBillsDrawingCode: TWideStringField;
  246. cdsBillsLookupDrawingCode: TWideStringField;
  247. cdsOrgBillsDrawingCode: TWideStringField;
  248. procedure DataModuleCreate(Sender: TObject);
  249. procedure DataModuleDestroy(Sender: TObject);
  250. procedure cdsBillsAfterOpen(DataSet: TDataSet);
  251. procedure cdsDrawingQuantityAfterOpen(DataSet: TDataSet);
  252. procedure cdsOrgBillsAfterInsert(DataSet: TDataSet);
  253. procedure cdsOrgDrawingQuantityAfterInsert(DataSet: TDataSet);
  254. procedure cdsOrgBillsBeforePost(DataSet: TDataSet);
  255. procedure cdsOrgBillsCodeChange(Sender: TField);
  256. procedure cdsOrgBillsBeforeEdit(DataSet: TDataSet);
  257. procedure cdsOrgBillsAfterPost(DataSet: TDataSet);
  258. procedure cdsOrgBillsAfterScroll(DataSet: TDataSet);
  259. procedure cdsOrgDrawingQuantityAfterPost(DataSet: TDataSet);
  260. procedure cdsOrgDrawingQuantityBeforePost(DataSet: TDataSet);
  261. procedure cdsOrgBillsQuantityGetText(Sender: TField; var Text: String;
  262. DisplayText: Boolean);
  263. procedure cdsOrgBillsQuantitySetText(Sender: TField;
  264. const Text: String);
  265. procedure cdsOrgDrawingQuantityDQuantity1GetText(Sender: TField;
  266. var Text: String; DisplayText: Boolean);
  267. procedure cdsOrgDrawingQuantityDQuantity1SetText(Sender: TField;
  268. const Text: String);
  269. procedure cdsOrgDrawingQuantityBeforeDelete(DataSet: TDataSet);
  270. procedure cdsBillsAfterPost(DataSet: TDataSet);
  271. procedure cdsXMJBillsAfterScroll(DataSet: TDataSet);
  272. procedure cdsOrgBillsUnitPriceGetText(Sender: TField; var Text: String;
  273. DisplayText: Boolean);
  274. procedure cdsXMJBillsQuantityGetText(Sender: TField; var Text: String;
  275. DisplayText: Boolean);
  276. procedure cdsOrgDrawingQuantityBeforeEdit(DataSet: TDataSet);
  277. procedure cdsBillsAfterInsert(DataSet: TDataSet);
  278. procedure cdsDrawingQuantityAfterInsert(DataSet: TDataSet);
  279. procedure cdsOrgBillsDeductGradeGetText(Sender: TField;
  280. var Text: String; DisplayText: Boolean);
  281. procedure cdsBillsLostNextSiblingCountChange(Sender: TField);
  282. procedure cdsOrgBillsLostNextSiblingCountChange(Sender: TField);
  283. procedure aqStatCalcFields(DataSet: TDataSet);
  284. procedure aqStatTotalCalcFields(DataSet: TDataSet);
  285. procedure cdsOrgDrawingQuantityAfterDelete(DataSet: TDataSet);
  286. procedure cdsOrgBillsIsAccQuantityChange(Sender: TField);
  287. private
  288. // 当前是否填工程量
  289. FCurIsGatherQ: Boolean;
  290. FDMExprs: TDMExprs;
  291. FProject: TObject;
  292. // FTriggerEvents: Boolean;
  293. FBillsTree: TScBillsTree;
  294. FXMJBillsTree: TXMJBillsTree;
  295. {std bills lib ctrl}
  296. FStdBillsCtrl: TObject;
  297. FStdLib: TObject;
  298. FStdTree: TStdBillsTree;
  299. FStdBQTree: TStdBillsTree;
  300. {code and b_code}
  301. FOldCode: string;
  302. FOldB_Code: string;
  303. { detail Items }
  304. FIsProjectBills: Boolean;
  305. FDetailItemsDM: TObject;
  306. FOldTotalPrice: Double;
  307. FBillsUndoRef: Integer;
  308. FDrawQtyUndoRef: Integer;
  309. FSavePoint: Integer;
  310. FSelList: TIntegerSList;
  311. FConnection: TADOConnection;
  312. {Event-Fields}
  313. FBillsAfterInsertEvt: TDataSetNotifyEvent;
  314. FBillsBeforePostEvt: TDataSetNotifyEvent;
  315. FBillsBeforeEditEvt: TDataSetNotifyEvent;
  316. FBillsAfterPostEvt: TDataSetNotifyEvent;
  317. FBillsAfterScrollEvt: TDataSetNotifyEvent;
  318. {UI}
  319. FEnabledUITreeEvt: TControlUIEvent;
  320. FEnabledUIDrawQtyEvt: TControlUIEvent;
  321. FDesignCodeEvt: TControlUIEvent;
  322. // 是否需要同步树:用于清单评分部分
  323. FNeedSyncTree: Boolean;
  324. FOnStat: TStatEvent;
  325. // 名称含“××”的清单项的父清单的Code
  326. FXXParentCodeSL: TStringList;
  327. FPBStdTreeFile: string;
  328. FBQStdTreeFile: string;
  329. FGatherXXItems: TStrings;
  330. // 判断是否在执行CancelChildItemIsAQ方法
  331. FOnCancelIsAQ: Boolean;
  332. function GetActive: Boolean;
  333. procedure SetActive(const Value: Boolean);
  334. procedure SetConnection(ACon: TADOConnection);
  335. function getConnection: TADOConnection;
  336. procedure SetStdBillsCtrl(Value: TObject);
  337. procedure SetIsProjectBills(const Value: Boolean);
  338. function GetBillsFullCode(AID: Integer): string;
  339. procedure InternalSave;
  340. procedure DeleteDQ(const ABillsID: Integer);
  341. procedure ClearBlankGatherXXItems;
  342. {gather DQquantity to Bills}
  343. procedure GatherDQQty(ABillsID: Integer; AGQ: Boolean);
  344. {auto match code form std lib, only used in beforepost}
  345. function IsGatherNode: Boolean; overload;
  346. function IsGatherNode(const aID: Integer): Boolean; overload;
  347. procedure SetDecimalDigit;
  348. procedure MatchCodeFromStdLib; overload;
  349. procedure MatchCodeFromStdLib(const AName, AUnits: string); overload;
  350. procedure CalculateParentQuantity;
  351. procedure AccQuantityToParentItem(AParentID: Integer; AQuantity1, AQuantity2: Double);
  352. function HasCalcPQChildItem(ABillsID: Integer): Boolean;
  353. procedure CancelChildItemIsAQ(ABillsID: Integer);
  354. procedure GatherChildDQuantity(ABillsID: Integer);
  355. {change children's code by parent}
  356. procedure ModifyCode(ANode: TZjIDTreeNode; const APreCode, AOldCode: string; AIsCode: Boolean);
  357. procedure ChildCodeModifyByParent(ANode: TZjIDTreeNode; const APreCode, AOldCode: string; AIsCode: Boolean);
  358. procedure ModifyCodeIncludeChildren(ANode: TZjIDTreeNode; const APreCode, AOldCode: string; AIsCode: Boolean);
  359. {sync billsitem code or b_code}
  360. procedure SyncBillsItemCode(const aID: Integer; const aCode, aB_Code, aName: string);
  361. {Events Handler}
  362. procedure BeginEvents(aExceptInsert: Boolean = False);
  363. procedure EndEvents;
  364. procedure ClearBillsFieldsTagAfterHandle;
  365. {Before Delete and After Delete}
  366. procedure BeforeDelete(aID: Integer; var aMajorIdx: Integer);
  367. procedure AfterDelete(aMajorIdx, aCount, aParentID, aPreID, aLastID: Integer);
  368. {clear quantity include children's}
  369. procedure ClearAllQuantity(ANode: TZjIDTreeNode);
  370. procedure ClearBillsQuantity(const ABillsID: Integer);
  371. procedure ClearDQQuantity(const ABillsID: Integer);
  372. {Filter xiang mu jie}
  373. function HasXMJ(aNode: TZjIDTreeNode): Boolean;
  374. procedure FilterXMJ(aNode: TZjIDTreeNode);
  375. { TODO -o-Litao : cancel cds operation }
  376. function GetSavePoint: Integer;
  377. procedure SetSavePoint(aSavePoint: Integer);
  378. {Remove zero Qty Bills}
  379. procedure ClearList(aList: TList);
  380. procedure FilterZeroQtyBills(aItems, aIDs: TList; aNode: TZjIDTreeNode);
  381. function FindIDRecord(AItems: TList; AID: Integer): PIDRecord;
  382. procedure UpdateRecords(aList: TList);
  383. procedure RemoveRecords(aIDs: TList); overload;
  384. procedure RemoveRecords(aIDs: string); overload;
  385. procedure UpdateRecord(aPreID, aNextID: Integer);
  386. function CanRemove(aNode: TZjIDTreeNode): Boolean;
  387. function IsQuantityZero(aID: Integer): Boolean;
  388. procedure FilterRemoveIDs(aNode: TZjIDTreeNode; aIDs: TList);
  389. function GetHasGatherQ: Boolean;
  390. function GetBQStdTreeFile: string;
  391. function GetPBStdTreeFile: string;
  392. procedure ReadBillGradeStdFile;
  393. public
  394. constructor Create(aProject: TObject);
  395. procedure Save;
  396. procedure SaveSerialNo;
  397. { Undo }
  398. procedure UnDoBillsText;
  399. procedure UnDoDrawQtyText;
  400. function CanUnDoBillsText: Boolean;
  401. function CanUnDoDrawQtyText: Boolean;
  402. function ShouldSave: Boolean;
  403. function HasDrawingQuantity(const AID: Integer): Boolean;
  404. {max IDs}
  405. function GetMaxBillsID: Integer;
  406. function GetMaxDrawingQuangtiyID: Integer;
  407. { TODO : Paste }
  408. function InsertItem(aNode: TZjIDTreeNode; const aCode, aName: string; aIsCode: Boolean): TZjIDTreeNode;
  409. { input excel }
  410. procedure AddBillsItem(ExlItem: TScExcelItem); overload;
  411. procedure AddBillsItem(GatherNode: TCacheGatherNode); overload;
  412. procedure AddDrawQItem(DQItem: TDrawingQuantityItem; SerinalNo: Integer = -1);
  413. procedure DeletePartSubItem(strList: TStringList);
  414. procedure ModifyNextSiblingID(const AID, ANextSiblingID: Integer); overload;
  415. function ModifyNextSiblingID(aID, aNewNextID: Integer; var aParentID, aNextID: Integer): Boolean; overload;
  416. procedure GetDQListByBillsID(ABillsID: Integer; GNode: TCacheGatherNode; var DQID: Integer);
  417. {gather}
  418. procedure ExtractBillsRecord(const AID: Integer; GatherNode: TCacheGatherNode);
  419. procedure ExtractBillsCode(const ID: Integer; var Code, BCode, Name: string);
  420. procedure PlusDesignQuantitys(const ID: Integer; GNode: TCacheGatherNode);
  421. procedure PlusBillsQuantity(const ID: Integer; GNode: TCacheGatherNode);
  422. procedure PlusDQDesignQuantitys(AID: Integer; GNode: TCacheGatherNode; var DQID: Integer);
  423. procedure DeleteAllBills(aDeleteDetail: Boolean = True);
  424. {PasteBills}
  425. procedure WriteRecIntoDB(aList: TList);
  426. { 删除工程量=0的清单 }
  427. procedure RemoveZeroQtyBills;
  428. { TODO : 导入工程量清单的单价 }
  429. procedure BeginImport;
  430. procedure EndImport;
  431. procedure AssignQtyItemUnitPrice(const aCode: string; aUnitPrice: Double);
  432. {节点收缩状态存取 }
  433. procedure SaveStatus;
  434. procedure ReadStatus(AID, ALength: Integer);
  435. {Delete Bills}
  436. procedure DeleteBills(aID: Integer); overload;
  437. procedure DeleteBills(aIDList: TStringList; aPreID, aLastID, aParentID: Integer); overload;
  438. function PreBlackFontItemID(ACurID: Integer): Integer;
  439. {control events}
  440. procedure BeginHandler(aExceptInsert: Boolean = False);
  441. procedure EndHandler;
  442. {BillsTree}
  443. procedure DisconnectBillsTree;
  444. procedure ConnectionBillsTree;
  445. { XMJBillsTree }
  446. procedure EnterXMJBills;
  447. procedure LeaveXMJBills;
  448. procedure LocateProjectBills;
  449. procedure SelectGatherNode(aNode: TZjIDTreeNode; aSelected: Boolean);
  450. function IsContainXXItem(ACode: string): Boolean;
  451. function HasSelected: Boolean;
  452. {clear cur node's Quantity}
  453. procedure ClearCurNodeQty;
  454. {show Levels}
  455. procedure ShowLevel(aLevelID: Integer);
  456. procedure OnlyShowXMJ;
  457. { Note: test tree is right }
  458. procedure CheckTree(aNode: TZjIDTreeNode);
  459. {Locate Bills}
  460. procedure GetChapterNames(ANames: TStrings);
  461. procedure LocateBills(aBillsID: Integer); overload;
  462. procedure LocateBills(const aCode: string); overload;
  463. {Selected}
  464. procedure ModifySelected(aID: Integer; aValue: Boolean);
  465. { Find Bills }
  466. function FindBills(aCdsDataset: TClientDataSet; aID: Integer): Boolean;
  467. { Calculate All Bills }
  468. function CalculateNode(aNode: TZjIDTreeNode): Double; overload;
  469. function CalculateSingle(aNode: TZjIDTreeNode): Double;
  470. procedure CalculateNode(aNode: TZjIDTreeNode; aTotalPrice: Double); overload;
  471. function CalculateOther(aFirstSum, aSecondSum: Double): Double;
  472. function CalculateAll: Double;
  473. procedure AscendSumToParent(aParent: TZjIDTreeNode; aOldSum, aNewSum: Double);
  474. procedure GatherBillsQuantity;
  475. // chenshilong, 2011-01-26 11:56:18 以下这部分清单评分
  476. procedure Grade(AllScope: Boolean = True);
  477. // 扣分规则。注意不是标准分,扣分不一定会将标准分扣完
  478. function StdDeductMark(ABillCategory: TBillCategory;
  479. AErrorCategory: TErrorCategory; ACount: Integer): Currency;
  480. function StdMark(AItem: TScBillsItem): Currency; overload;
  481. function StdMark(ACode, AB_Code: string): Currency; overload;
  482. function Stat: Currency;
  483. procedure ClearUserFlags;
  484. procedure CancelError(AEC: TErrorCategory);
  485. procedure AddError(AEC: TErrorCategory; ACount: Integer);
  486. // 递归删除最后节点的父节点的单位
  487. procedure DeleteLastParentUnit(AID: Integer);
  488. // 根据树节点数据刷新cdsOrgBills
  489. procedure RefreshByItem(AItem: TScBillsItem);
  490. procedure SyncGradeFromTreeNodeToDataSet(AItem: TScBillsItem);
  491. procedure SyncGradeFromDataSetToTreeNode(ACDS: TClientDataSet);
  492. // 用户手工修改了清单评分数据
  493. procedure SetUserModifiedGrade;
  494. // 宽松对比,AStr1和AStr2是否相同,如忽略括号全半角等。
  495. function LooseCompareIsSame(AStr1, AStr2: string): Boolean;
  496. procedure Save_SerialNo_ChapterID_FullCode;
  497. // 清空所有清单单价 chenshilong, 2011-07-26
  498. procedure ClearAllUnitPrices;
  499. property Active: Boolean read GetActive write SetActive;
  500. property Connection: TADOConnection read getConnection write SetConnection;
  501. property BillsTree: TScBillsTree read FBillsTree;
  502. property XMJBillsTree: TXMJBillsTree read FXMJBillsTree;
  503. property DMExprs: TDMExprs read FDMExprs write FDMExprs;
  504. property DetailItemsDM: TObject read FDetailItemsDM;
  505. property IsProjectBills: Boolean read FIsProjectBills write SetIsProjectBills;
  506. {std bills lib}
  507. property StdBillsCtrl: TObject read FStdBillsCtrl write SetStdBillsCtrl;
  508. {Events}
  509. property EnabledUITreeEvt: TControlUIEvent read FEnabledUITreeEvt write FEnabledUITreeEvt;
  510. property EnabledUIDrawQtyEvt: TControlUIEvent read FEnabledUIDrawQtyEvt write FEnabledUIDrawQtyEvt;
  511. property DesignCodeEvt: TControlUIEvent read FDesignCodeEvt write FDesignCodeEvt;
  512. property OnStat: TStatEvent read FOnStat write FOnStat;
  513. property HasGatherQ: Boolean read GetHasGatherQ;
  514. property Project: TObject read FProject write FProject;
  515. property PBStdTreeFile: string read GetPBStdTreeFile write FPBStdTreeFile;
  516. property BQStdTreeFile: string read GetBQStdTreeFile write FBQStdTreeFile;
  517. procedure CloneActive(IsActive: Boolean);
  518. end;
  519. var
  520. DMDataBase: TDMDataBase;
  521. // 获取所有子结点个数(包含子子结点,但不包括自身)
  522. function GetAllChildrenCount(ANode: TZjIDTreeNode): Integer;
  523. implementation
  524. uses
  525. Graphics,
  526. ScStdBillsCtrl,
  527. Math,
  528. ScEvaluate,
  529. Windows,
  530. Forms,
  531. Controls,
  532. ScConfig,
  533. StrUtils,
  534. ScProjectManager,
  535. DetailItemsDM, ScProgressFrm,
  536. StdBillsLibDM, IniFiles, {CslTimeDebug,} MainForm;
  537. {$R *.dfm}
  538. { TDMDataBase }
  539. function TDMDataBase.HasDrawingQuantity(const AID: Integer): Boolean;
  540. begin
  541. Result := cdsDQForLocate.FindKey([AID]);
  542. end;
  543. procedure TDMDataBase.DataModuleCreate(Sender: TObject);
  544. var sXXFile: string;
  545. begin
  546. FXXParentCodeSL := TStringList.Create;
  547. FGatherXXItems := TStringList.Create;
  548. sXXFile := ExtractFilePath(Application.ExeName) + 'Data\XXItem.dll';
  549. if FileExists(sXXFile) then
  550. FXXParentCodeSL.LoadFromFile(sXXFile);
  551. sXXFile := ExtractFilePath(Application.ExeName) + 'Data\GatherXXItem.ini';
  552. if FileExists(sXXFile) then
  553. FGatherXXItems.LoadFromFile(sXXFile);
  554. ClearBlankGatherXXItems;
  555. FBillsTree := TScBillsTree.Create;
  556. FBillsTree.Bills := Self;
  557. FBillsTree.AutoExpand := True;
  558. FBillsTree.KeyFieldName := SID;
  559. FBillsTree.ParentFieldName := sParentID;
  560. FBillsTree.NextSiblingFieldName := sNextSiblingID;
  561. cdsBills.IndexDefs.Clear;
  562. cdsBills.IndexDefs.Add('BillsIDidx', SID, [ixPrimary, ixUnique]);
  563. cdsBills.IndexDefs.Add('idxB_Code', 'B_Code', []);
  564. cdsBills.IndexName := 'BillsIDidx';
  565. cdsDrawingQuantity.IndexDefs.Add('IDidx', SID, [ixPrimary, ixUnique]);
  566. cdsDrawingQuantity.IndexName := 'IDidx';
  567. FSelList := TIntegerSList.Create;
  568. { XmjBillsTree }
  569. FXMJBillsTree := TXMJBillsTree.Create;
  570. FXMJBillsTree.Bills := Self;
  571. FXMJBillsTree.AutoExpand := True;
  572. FXMJBillsTree.KeyFieldName := SID;
  573. FXMJBillsTree.ParentFieldName := sParentID;
  574. FXMJBillsTree.NextSiblingFieldName := sNextSiblingID;
  575. {add vaildchars for exprs calc}
  576. cdsOrgBillsQuantity.ValidChars := cdsOrgBillsQuantity.ValidChars + ExprsCharSet;
  577. cdsOrgBillsDesignQuantity.ValidChars := cdsOrgBillsDesignQuantity.ValidChars + ExprsCharSet;
  578. cdsOrgBillsDesignQuantity2.ValidChars := cdsOrgBillsDesignQuantity2.ValidChars + ExprsCharSet;
  579. cdsOrgDrawingQuantityDQuantity1.ValidChars := cdsOrgDrawingQuantityDQuantity1.ValidChars + ExprsCharSet;
  580. FNeedSyncTree := True;
  581. ReadBillGradeStdFile;
  582. end;
  583. procedure TDMDataBase.DataModuleDestroy(Sender: TObject);
  584. begin
  585. FXXParentCodeSL.Free;
  586. FGatherXXItems.Free;
  587. FBillsTree.Free;
  588. FXMJBillsTree.Free;
  589. FSelList.Free;
  590. end;
  591. function TDMDataBase.GetActive: Boolean;
  592. begin
  593. Result := cdsBills.Active and cdsDrawingQuantity.Active;
  594. end;
  595. procedure TDMDataBase.SetActive(const Value: Boolean);
  596. begin
  597. cdsBills.Active := Value;
  598. cdsDrawingQuantity.Active := Value;
  599. cdsStat.Active := Value;
  600. cdsStatTotal.Active := Value;
  601. if Value then
  602. cdsStat.IndexFieldNames := 'ChapterID';
  603. end;
  604. procedure TDMDataBase.cdsBillsAfterOpen(DataSet: TDataSet);
  605. begin
  606. if cdsBills.Active then
  607. begin
  608. cdsOrgBills.CloneCursor(cdsBills, True);
  609. cdsBillsLookup.CloneCursor(cdsBills, True);
  610. // ConnectionBillsTree;
  611. end;
  612. end;
  613. procedure TDMDataBase.cdsDrawingQuantityAfterOpen(DataSet: TDataSet);
  614. begin
  615. cdsDQForLocate.CloneCursor(cdsDrawingQuantity, True);
  616. cdsDQForLocate.IndexFieldNames := Format('%s;%s', [sBillsID, sSerinalNO]);
  617. cdsOrgDrawingQuantity.CloneCursor(cdsDrawingQuantity, True);
  618. cdsOrgDrawingQuantity.MasterSource := dsBillsDrawing;
  619. {主表字段}
  620. cdsOrgDrawingQuantity.MasterFields := SID;
  621. {从表字段, 通过索引字段来设}
  622. cdsOrgDrawingQuantity.IndexFieldNames := Format('%s;%s', [sBillsID, sSerinalNO]);
  623. end;
  624. function TDMDataBase.getConnection: TADOConnection;
  625. begin
  626. Result := FConnection;
  627. end;
  628. procedure TDMDataBase.SetConnection(ACon: TADOConnection);
  629. begin
  630. FConnection := ACon;
  631. atBills.Connection := FConnection;
  632. atDrawingQuantity.Connection := FConnection;
  633. atStat.Connection := FConnection;
  634. aqStat.Connection := FConnection;
  635. atStatTotal.Connection := FConnection;
  636. aqStatTotal.Connection := FConnection;
  637. end;
  638. function TDMDataBase.GetMaxBillsID: Integer;
  639. begin
  640. cdsBills.Last;
  641. Result := cdsBillsID.Value + 1;
  642. if Result < 300 then Result := 300;
  643. end;
  644. procedure TDMDataBase.cdsOrgBillsAfterInsert(DataSet: TDataSet);
  645. var
  646. iMaxBillsID: Integer;
  647. begin
  648. iMaxBillsID := GetMaxBillsID;
  649. cdsOrgBillsID.Value := iMaxBillsID;
  650. FBillsUndoRef := 0;
  651. cdsOrgBillsIsCreatePriceAnalysis.Value := True;
  652. if Assigned(FStdBillsCtrl) then
  653. TStdBillsCtrl(FStdBillsCtrl).DMStdBillsLib.AutoIncreaseBillsCode;
  654. end;
  655. function TDMDataBase.GetMaxDrawingQuangtiyID: Integer;
  656. begin
  657. cdsDrawingQuantity.Last;
  658. Result := cdsDrawingQuantityID.Value + 1;
  659. end;
  660. procedure TDMDataBase.cdsOrgDrawingQuantityAfterInsert(DataSet: TDataSet);
  661. begin
  662. // if FTriggerEvents then Exit;
  663. FDrawQtyUndoRef := 0;
  664. cdsOrgDrawingQuantityID.Value := GetMaxDrawingQuangtiyID;
  665. cdsOrgDrawingQuantitySerinalNo.Value := cdsOrgDrawingQuantity.RecordCount + 1;
  666. end;
  667. procedure TDMDataBase.Save;
  668. begin
  669. CreateProgressForm(100, '正在保存数据,请稍候>>>');
  670. AddProgressForm(10, '正在保存流水号和章节号...');
  671. FBillsUndoRef := 0;
  672. FDrawQtyUndoRef := 0;
  673. {InternalSave; }
  674. Save_SerialNo_ChapterID_FullCode;
  675. AddProgressForm(20, '正在保存清单,根据项目的大小,可能需要较长时间...');
  676. cdsBills.ApplyUpdates(0);
  677. AddProgressForm(20, '正在保存图纸工程量...');
  678. cdsDrawingQuantity.ApplyUpdates(0);
  679. AddProgressForm(10, '正在保存计算公式...');
  680. AddProgressForm(10, '正在保存评分统计...');
  681. cdsStat.ApplyUpdates(0);
  682. cdsStatTotal.ApplyUpdates(0);
  683. CloseProgressForm;
  684. end;
  685. function TDMDataBase.ShouldSave: Boolean;
  686. begin
  687. Result := (cdsBills.ChangeCount > 0) or (cdsDrawingQuantity.ChangeCount > 0)
  688. or (cdsStat.ChangeCount > 0);
  689. end;
  690. procedure TDMDataBase.AddBillsItem(ExlItem: TScExcelItem);
  691. begin
  692. cdsBills.Insert;
  693. cdsBillsID.Value := ExlItem.ID;
  694. cdsBillsParentID.Value := ExlItem.ParentID;
  695. cdsBillsNextSiblingID.Value := ExlItem.NextSiblingID;
  696. cdsBillsCode.Value := ExlItem.Code;
  697. cdsBillsUnitPrice.Value := ScRoundTo(ExlItem.Price, -2);
  698. cdsBillsTotalPrice.Value := ScRoundTo(ExlItem.TotalPrice, 0);
  699. if SameText(ExlItem.Code, '') then
  700. begin
  701. cdsBillsQuantity.Value := ScRoundTo(ExlItem.Quantity, -3);
  702. {if cdsBillsQuantity.AsFloat <> 0 then
  703. begin
  704. cdsBillsUnitPrice.Value := ScRoundTo(ExlItem.TotalPrice/cdsBillsQuantity.AsFloat, -2);
  705. cdsBillsTotalPrice.Value := ScRoundTo(cdsBillsQuantity.AsFloat*cdsBillsUnitPrice.AsFloat, 0);
  706. end; }
  707. end
  708. else
  709. begin
  710. cdsBillsDesignQuantity.Value := ScRoundTo(ExlItem.Quantity1, -3);
  711. cdsBillsDesignQuantity2.Value := ScRoundTo(ExlItem.Quantity2, -3);
  712. {if cdsBillsDesignQuantity.AsFloat <> 0 then
  713. begin
  714. cdsBillsTotalPrice.Value := ScRoundTo(ExlItem.TotalPrice, 0);
  715. cdsBillsDesignPrice.AsFloat := ScRoundTo(cdsBillsTotalPrice.AsFloat/cdsBillsDesignQuantity.AsFloat, -2);
  716. end; }
  717. end;
  718. cdsBillsB_Code.Value := ExlItem.BCode;
  719. cdsBillsName.Value := ExlItem.Name;
  720. cdsBillsUnits.Value := ExlItem.Units;
  721. cdsBillsMemoStr.Value := ExlItem.MemoString;
  722. cdsBillsIsPreDefine.Value := ExlItem.ParentID = -1;
  723. cdsBills.Post;
  724. end;
  725. procedure TDMDataBase.AddDrawQItem(DQItem: TDrawingQuantityItem; SerinalNo: Integer);
  726. begin
  727. cdsDrawingQuantity.Insert;
  728. cdsDrawingQuantityID.Value := DQItem.ID;
  729. if SerinalNo = -1 then
  730. cdsDrawingQuantitySerinalNo.Value := DQItem.SerinalNo
  731. else
  732. cdsDrawingQuantitySerinalNo.Value := SerinalNo;
  733. cdsDrawingQuantityBillsID.Value := DQItem.BillsID;
  734. cdsDrawingQuantityName.Value := DQItem.Name;
  735. cdsDrawingQuantityUnits.Value := DQItem.Units;
  736. if DQItem.DesignQuantity1 <> 0 then
  737. cdsDrawingQuantityDQuantity1.Value := ScRoundTo(DQItem.DesignQuantity1, -3);
  738. if DQItem.DesignQuantity2 <> 0 then
  739. cdsDrawingQuantityDQuantity2.Value := ScRoundTo(DQItem.DesignQuantity2, -3);
  740. cdsDrawingQuantityMemoContext.Value := DQItem.MemoContext;
  741. cdsDrawingQuantity.Post;
  742. end;
  743. function ComPareItemsID(Obj1, Obj2: Pointer): Integer;
  744. begin
  745. if TBillsOrderItem(Obj1).ID < TBillsOrderItem(Obj2).ID then Result := -1
  746. else if TBillsOrderItem(Obj1).ID > TBillsOrderItem(Obj2).ID then Result := 1
  747. else Result := 0;
  748. end;
  749. procedure TDMDataBase.InternalSave;
  750. { procedure ClearObjects(ObjList: TList);
  751. var
  752. I: Integer;
  753. ObjItem: TBillsOrderItem;
  754. begin
  755. for I := ObjList.Count - 1 downto 0 do
  756. begin
  757. ObjItem := TBillsOrderItem(ObjList[I]);
  758. ObjItem.Free;
  759. end;
  760. end;
  761. procedure ExtractBillsPropertities(ObjList: TList);
  762. var
  763. I: Integer;
  764. ObjBills: TBillsOrderItem;
  765. billsItem: TScBillsItem;
  766. begin
  767. for I := 0 to BillsTree.Count - 1 do
  768. begin
  769. billsItem := BillsTree.Items[I];
  770. ObjBills := TBillsOrderItem.Create;
  771. ObjBills.ID := billsItem.ID;
  772. ObjBills.MajorIndex := billsItem.MajorIndex;
  773. ObjBills.CharpterID := billsItem.ChapterID;
  774. ObjBills.HasChildren := billsItem.HasChildren;
  775. ObjList.Add(ObjBills);
  776. end;
  777. ObjList.Sort(ComPareItemsID);
  778. end;
  779. var
  780. I, CurID: Integer;
  781. ObjectsList: TList;
  782. DataSet: TDataSet;
  783. Item: TScBillsItem;
  784. ObjBills: TBillsOrderItem; }
  785. begin
  786. { ObjectsList := TList.Create;
  787. try
  788. DataSet := nil;
  789. CurID := BillsTree.SelectedIndex;
  790. ExtractBillsPropertities(ObjectsList);
  791. if Assigned(BillsTree.DataSet) then
  792. begin
  793. DataSet := BillsTree.DataSet;
  794. BillsTree.DataSet := nil;
  795. end;
  796. try
  797. I := 0;
  798. cdsBills.First;
  799. while not cdsBills.Eof do
  800. begin
  801. ObjBills := TBillsOrderItem(ObjectsList[I]);
  802. cdsBills.Edit;
  803. cdsBillsSerialNo.Value := ObjBills.MajorIndex;
  804. cdsBillsChapterID.Value := ObjBills.CharpterID;
  805. cdsBillsIsLeaf.Value := not ObjBills.HasChildren;
  806. // cdsBillsFullCode.Value := GetBillsFullCode(cdsBillsID.Value);
  807. cdsBills.Post;
  808. cdsBills.Next;
  809. Inc(I);
  810. end;
  811. finally
  812. if Assigned(DataSet) then
  813. BillsTree.DataSet := DataSet;
  814. Item := TScBillsItem(BillsTree.Items[curID]);
  815. Item.LocateDBRecord;
  816. end;
  817. finally
  818. ClearObjects(ObjectsList);
  819. ObjectsList.Free;
  820. end; }
  821. end;
  822. procedure TDMDataBase.DeletePartSubItem(strList: TStringList);
  823. var
  824. I: Integer;
  825. IDLstString: string;
  826. cdsDataSet: TClientDataSet;
  827. begin
  828. for I := 0 to strList.Count - 1 do
  829. begin
  830. IDLstString := strList.Strings[I];
  831. cdsDataSet := TClientDataSet.Create(nil);
  832. cdsDataSet.CloneCursor(cdsBills, True);
  833. try
  834. cdsDataSet.Filter := IDLstString;
  835. cdsDataSet.Filtered := True;
  836. cdsDataSet.First;
  837. while not cdsDataSet.Eof do
  838. begin
  839. DeleteDQ(cdsDataSet.FieldByName(SID).AsInteger);
  840. cdsDataSet.Delete;
  841. end;
  842. finally
  843. cdsDataSet.Free;
  844. end;
  845. end;
  846. end;
  847. procedure TDMDataBase.ModifyNextSiblingID(const AID,
  848. ANextSiblingID: Integer);
  849. begin
  850. if AID = -1 then Exit;
  851. if cdsBills.FindKey([AID]) then
  852. begin
  853. cdsBills.Edit;
  854. cdsBillsNextSiblingID.Value := ANextSiblingID;
  855. cdsBills.Post;
  856. end;
  857. end;
  858. procedure TDMDataBase.DeleteDQ(const ABillsID: Integer);
  859. var
  860. cdsDelete: TClientDataSet;
  861. begin
  862. cdsDelete := TClientDataSet.Create(nil);
  863. try
  864. cdsDelete.CloneCursor(cdsDrawingQuantity, True);
  865. cdsDelete.IndexFieldNames := sBillsID;
  866. cdsDelete.SetRange([ABillsID], [ABillsID]);
  867. cdsDelete.First;
  868. while not cdsDelete.Eof do
  869. begin
  870. FDMExprs.Delete(Exprs_DrawQty_ID, cdsDelete.FieldByName(SID).AsInteger);
  871. cdsDelete.Delete;
  872. end;
  873. finally
  874. cdsDelete.Free;
  875. end;
  876. end;
  877. procedure TDMDataBase.AddBillsItem(GatherNode: TCacheGatherNode);
  878. begin
  879. cdsBills.Insert;
  880. cdsBillsID.Value := GatherNode.ID;
  881. cdsBillsParentID.Value := GatherNode.ParentID;
  882. cdsBillsNextSiblingID.Value := GatherNode.NextSiblingID;
  883. cdsBillsCode.Value := GatherNode.Code;
  884. //cdsBillsTotalPrice.Value := ScRoundTo(GatherNode.TotalPrice, 0);
  885. if SameText(GatherNode.Code, '') then
  886. begin
  887. cdsBillsQuantity.Value := ScRoundTo(GatherNode.Quantity, -3);
  888. if cdsBillsQuantity.AsFloat <> 0 then
  889. begin
  890. cdsBillsUnitPrice.Value := ScRoundTo(GatherNode.TotalPrice/cdsBillsQuantity.AsFloat, -2);
  891. cdsBillsTotalPrice.Value := ScRoundTo(cdsBillsQuantity.AsFloat*cdsBillsUnitPrice.AsFloat, 0);
  892. end;
  893. end
  894. else
  895. begin
  896. cdsBillsDesignQuantity.Value := ScRoundTo(GatherNode.DesignQuantity1, -3);
  897. cdsBillsDesignQuantity2.Value := ScRoundTo(GatherNode.DesignQuantity2, -3);
  898. if cdsBillsDesignQuantity.AsFloat <> 0 then
  899. begin
  900. cdsBillsTotalPrice.Value := ScRoundTo(GatherNode.TotalPrice, 0);
  901. cdsBillsDesignPrice.AsFloat := ScRoundTo(cdsBillsTotalPrice.AsFloat/cdsBillsDesignQuantity.AsFloat, -2);
  902. end;
  903. end;
  904. cdsBillsB_Code.Value := GatherNode.BCode;
  905. cdsBillsName.Value := GatherNode.Name;
  906. cdsBillsUnits.Value := GatherNode.Units;
  907. cdsBillsMemoStr.Value := GatherNode.MemoString;
  908. cdsBillsIsPreDefine.Value := GatherNode.IsPreDefined;
  909. cdsBills.Post;
  910. end;
  911. procedure TDMDataBase.GetDQListByBillsID(ABillsID: Integer;
  912. GNode: TCacheGatherNode; var DQID: Integer);
  913. var
  914. DQItem: TDrawingQuantityItem;
  915. cdsDQList: TClientDataSet;
  916. begin
  917. cdsDQList := TClientDataSet.Create(nil);
  918. cdsDQList.CloneCursor(cdsDrawingQuantity, True);
  919. cdsDQList.IndexFieldNames := sBillsID;
  920. cdsDQList.SetRange([ABillsID], [ABillsID]);
  921. cdsDQList.First;
  922. while not cdsDQList.Eof do
  923. begin
  924. DQItem := TDrawingQuantityItem.Create;
  925. DQItem.ID := DQID;
  926. DQItem.BillsID := GNode.ID;
  927. DQItem.Name := cdsDQList.FieldByName(sName).AsString;
  928. DQItem.Units := cdsDQList.FieldByName(sUnits).AsString;
  929. DQItem.DesignQuantity1 := cdsDQList.FieldByName(sDQuantity1).AsFloat;
  930. DQItem.DesignQuantity2 := cdsDQList.FieldByName(sDQuantity2).AsFloat;
  931. DQItem.MemoContext := cdsDQList.FieldByName(sMemoContext).AsString;
  932. GNode.DQList.Add(DQItem);
  933. Inc(DQID);
  934. cdsDQList.Next;
  935. end;
  936. cdsDQList.Free;
  937. end;
  938. procedure TDMDataBase.ExtractBillsRecord(const AID: Integer; GatherNode: TCacheGatherNode);
  939. begin
  940. if cdsBills.FindKey([AID]) then
  941. begin
  942. GatherNode.Code := cdsBillsCode.AsString;
  943. GatherNode.Quantity := cdsBillsQuantity.Value;
  944. GatherNode.BCode := cdsBillsB_Code.AsString;
  945. GatherNode.OldBCode := GatherNode.BCode;
  946. GatherNode.DesignQuantity1 := cdsBillsDesignQuantity.Value;
  947. GatherNode.DesignQuantity2 := cdsBillsDesignQuantity2.Value;
  948. GatherNode.Name := cdsBillsName.AsString;
  949. GatherNode.Units := cdsBillsUnits.AsString;
  950. GatherNode.UnitPrice := cdsBillsUnitPrice.Value;
  951. if cdsBillsB_Code.AsString <> '' then
  952. GatherNode.TotalPrice := cdsBillsQuantity.AsFloat*cdsBillsUnitPrice.AsFloat
  953. else
  954. GatherNode.TotalPrice := cdsBillsTotalPrice.AsFloat;
  955. GatherNode.MemoString := cdsBillsMemoStr.AsString;
  956. GatherNode.IsPreDefined := cdsBillsIsPreDefine.AsBoolean;
  957. end;
  958. end;
  959. procedure TDMDataBase.ExtractBillsCode(const ID: Integer;
  960. var Code, BCode, Name: string);
  961. begin
  962. if cdsBills.FindKey([ID]) then
  963. begin
  964. Code := cdsBillsCode.Value;
  965. BCode := cdsBillsB_Code.Value;
  966. Name := cdsBillsName.Value;
  967. end;
  968. end;
  969. procedure TDMDataBase.PlusBillsQuantity(const ID: Integer;
  970. GNode: TCacheGatherNode);
  971. begin
  972. if cdsBills.FindKey([ID]) then
  973. begin
  974. GNode.Quantity := GNode.Quantity + cdsBillsQuantity.AsFloat;
  975. GNode.TotalPrice := GNode.TotalPrice + cdsBillsQuantity.AsFloat*cdsBillsUnitPrice.AsFloat;
  976. end;
  977. end;
  978. procedure TDMDataBase.PlusDesignQuantitys(const ID: Integer;
  979. GNode: TCacheGatherNode);
  980. begin
  981. if cdsBills.FindKey([ID]) then
  982. begin
  983. GNode.DesignQuantity1 := GNode.DesignQuantity1 + cdsBillsDesignQuantity.Value;
  984. GNode.DesignQuantity2 := GNode.DesignQuantity2 + cdsBillsDesignQuantity2.Value;
  985. GNode.TotalPrice := GNode.TotalPrice + cdsBillsTotalPrice.Value;
  986. end;
  987. end;
  988. procedure TDMDataBase.PlusDQDesignQuantitys(AID: Integer; GNode: TCacheGatherNode;
  989. var DQID: Integer);
  990. var
  991. I: Integer;
  992. blFounded: Boolean;
  993. DQItem: TDrawingQuantityItem;
  994. CDS1: TClientDataSet;
  995. begin
  996. CDS1 := TClientDataSet.Create(nil);
  997. CDS1.CloneCursor(cdsDrawingQuantity, True);
  998. CDS1.IndexFieldNames := sBillsID;
  999. CDS1.SetRange([AID], [AID]);
  1000. CDS1.First;
  1001. while not CDS1.Eof do
  1002. begin
  1003. blFounded := False;
  1004. for I := 0 to GNode.DQList.Count - 1 do
  1005. begin
  1006. DQItem := TDrawingQuantityItem(GNode.DQList[I]);
  1007. if SameText(DQItem.Name, CDS1.FieldByName(sName).AsString) and
  1008. SameText(DQItem.Units, CDS1.FieldByName(sUnits).AsString)
  1009. then
  1010. begin
  1011. DQItem.DesignQuantity1 := DQItem.DesignQuantity1 + CDS1.FieldByName(sDQuantity1).AsFloat;
  1012. DQItem.DesignQuantity2 := DQItem.DesignQuantity2 + CDS1.FieldByName(sDQuantity2).AsFloat;
  1013. blFounded := True;
  1014. Break;
  1015. end;
  1016. end;
  1017. if not blFounded then
  1018. begin
  1019. DQItem := TDrawingQuantityItem.Create;
  1020. DQItem.ID := DQID;
  1021. DQItem.BillsID := GNode.ID;
  1022. DQItem.Name := CDS1.FieldByName(sName).AsString;
  1023. DQItem.Units := CDS1.FieldByName(sUnits).AsString;
  1024. DQItem.DesignQuantity1 := CDS1.FieldByName(sDQuantity1).AsFloat;
  1025. DQItem.DesignQuantity2 := CDS1.FieldByName(sDQuantity2).AsFloat;
  1026. DQItem.MemoContext := CDS1.FieldByName(sMemoContext).AsString;
  1027. GNode.DQList.Add(DQItem);
  1028. Inc(DQID);
  1029. end;
  1030. CDS1.Next;
  1031. end;
  1032. CDS1.Free;
  1033. end;
  1034. procedure TDMDataBase.DeleteAllBills(aDeleteDetail: Boolean);
  1035. begin
  1036. cdsBills.First;
  1037. while not cdsBills.Eof do
  1038. begin
  1039. if aDeleteDetail then
  1040. begin
  1041. DeleteDQ(cdsBillsID.AsInteger);
  1042. FDMExprs.Delete(Exprs_Bills_ID, cdsBillsID.AsInteger);
  1043. end;
  1044. cdsBills.Delete;
  1045. end;
  1046. end;
  1047. procedure TDMDataBase.cdsOrgBillsBeforePost(DataSet: TDataSet);
  1048. var
  1049. bCanMatch: Boolean;
  1050. begin
  1051. bCanMatch := (cdsOrgBillsCode.Tag = 1) or (cdsOrgBillsB_Code.Tag = 1);
  1052. if bCanMatch then
  1053. begin
  1054. if (cdsOrgBillsCode.AsString <> '') and (cdsOrgBillsB_Code.AsString <> '') then
  1055. begin
  1056. DataSet.Cancel;
  1057. raise Exception.Create('项目编号和清单编号不能同时存在!');
  1058. end;
  1059. end;
  1060. // Modified By MaiXinRong 2012-03-21
  1061. {Is Accept Quantity Input}
  1062. if (cdsOrgBillsDesignQuantity.Tag = 1) or (cdsOrgBillsDesignQuantity2.Tag = 1) then
  1063. begin
  1064. if HasCalcPQChildItem(cdsOrgBillsID.AsInteger) then
  1065. begin
  1066. if MessageQuest('该清单下有子清单勾选填父项量,是否修改并取消子清单的填父项量勾选?','询问') then
  1067. CancelChildItemIsAQ(cdsBillsID.AsInteger)
  1068. else
  1069. // 将DataSet.Cancel注释掉,因为在这里直接Cancel后会报错,所以这里不做修改,直接去保持原有的状态
  1070. // 在后面的AfterPost中去保持原来的方式计算一遍,这也相当于不做修改
  1071. // 2012.5.8HXY
  1072. // DataSet.Cancel;
  1073. end;
  1074. //CalculateParentQuantity;
  1075. //cdsOrgBillsDesignQuantity.Tag := 0;
  1076. //cdsOrgBillsDesignQuantity2.Tag := 0;
  1077. end;
  1078. if cdsOrgBillsIsAccQuantity.Tag = 1 then
  1079. begin
  1080. if cdsOrgBillsB_Code.AsString <> '' then
  1081. begin
  1082. cdsOrgBillsIsAccQuantity.Clear;
  1083. cdsOrgBillsIsAccQuantity.Tag := 1;
  1084. end;
  1085. end;
  1086. { Moved to AfterPost, As Used Gather Replace Addition and subtraction}
  1087. {
  1088. if cdsOrgBillsIsAccQuantity.Tag = 1 then
  1089. begin
  1090. CalculateParentQuantity;
  1091. cdsOrgBillsIsAccQuantity.Tag := 0;
  1092. end;
  1093. }
  1094. {set float number decimal digit}
  1095. SetDecimalDigit;
  1096. {match info from std lib}
  1097. if Assigned(FStdBillsCtrl) and bCanMatch and (cdsOrgBillsName.AsString = '') then
  1098. MatchCodeFromStdLib;
  1099. {refresh custom step record when bills node uplevel or downlevel }
  1100. if (DataSet.State = dsEdit) and ((cdsOrgBillsParentID.Tag = 1) or (cdsOrgBillsNextSiblingID.Tag = 1)) then
  1101. begin
  1102. FBillsUndoRef := 0;
  1103. cdsOrgBills.AfterScroll(nil);
  1104. cdsOrgBillsParentID.Tag := 0;
  1105. cdsOrgBillsNextSiblingID.Tag := 0;
  1106. end;
  1107. end;
  1108. // chenshilong, 2011-07-13
  1109. function TDMDataBase.GetBillsFullCode(AID: Integer): string;
  1110. var
  1111. vItem: TScBillsItem;
  1112. sCode, sBCode: string;
  1113. begin
  1114. Result := '';
  1115. vItem := BillsTree.BillsItem[AID];
  1116. if vItem = nil then Exit;
  1117. sCode := Trim(vItem.Code);
  1118. sBCode := Trim(vItem.B_Code);
  1119. // 预算项目节,FullCode直接等于自身的Code
  1120. if (sCode <> '') then
  1121. Result := sCode
  1122. else // 清单子目号,FullCode等于最底层预算项目节Code
  1123. begin
  1124. while Assigned(vItem) and (Trim(vItem.Code) = '') do
  1125. begin
  1126. vItem := TScBillsItem(vItem.Parent);
  1127. end;
  1128. if Assigned(vItem) then
  1129. Result := Trim(vItem.Code);
  1130. end;
  1131. end;
  1132. procedure TDMDataBase.BeginHandler(aExceptInsert: Boolean);
  1133. begin
  1134. BeginEvents(aExceptInsert);
  1135. end;
  1136. procedure TDMDataBase.EndHandler;
  1137. begin
  1138. EndEvents;
  1139. ClearBillsFieldsTagAfterHandle;
  1140. {this code is used for showing custom step}
  1141. FBillsAfterScrollEvt(nil);
  1142. end;
  1143. function TDMDataBase.PreBlackFontItemID(ACurID: Integer): Integer;
  1144. const
  1145. arrayID: array [0..5] of Integer = (1, 2, 3, 4, 8, 9);
  1146. var
  1147. i, iPos: Integer;
  1148. begin
  1149. Result := 1;
  1150. iPos := 0;
  1151. for i :=Low(arrayID) to High(arrayID) do
  1152. begin
  1153. if arrayID[i] = ACurID then
  1154. begin
  1155. iPos := i;
  1156. Break;
  1157. end;
  1158. end;
  1159. for i := iPos - 1 downto Low(arrayID) do
  1160. begin
  1161. if cdsBills.FindKey([arrayID[i]]) then
  1162. begin
  1163. Result := arrayID[i];
  1164. Break;
  1165. end;
  1166. end;
  1167. end;
  1168. procedure TDMDataBase.ChildCodeModifyByParent(ANode: TZjIDTreeNode;
  1169. const APreCode, AOldCode: string; AIsCode: Boolean);
  1170. var
  1171. I: Integer;
  1172. vNode: TZjIDTreeNode;
  1173. begin
  1174. for I := 0 to ANode.ChildCount - 1 do
  1175. begin
  1176. vNode := ANode.ChildNodes[I];
  1177. ModifyCode(vNode, APreCode, AOldCode, AIsCode);
  1178. end;
  1179. end;
  1180. {function GetNewCode(const AOldCode, AOldParentCode, APreCode: string): string;
  1181. begin
  1182. Result := AOldCode;
  1183. if Result = '' then Exit;
  1184. if AOldParentCode = '' then
  1185. begin
  1186. if APreCode <> '' then
  1187. Result := format('%s-%s', [APreCode, Result]);
  1188. end
  1189. else
  1190. begin
  1191. if APreCode = '' then
  1192. begin
  1193. Delete(Result, 1, Length(AOldParentCode) + 1);
  1194. end
  1195. else
  1196. begin
  1197. Delete(Result, 1, Length(AOldParentCode));
  1198. Result := APreCode + Result;
  1199. end;
  1200. end;
  1201. end; }
  1202. function ReplaceCodePreFix(const APreFixCode, AFullCode: string): string;
  1203. function GetLastcode(const ACode: string): string;
  1204. var
  1205. I: Integer;
  1206. begin
  1207. Result := '';
  1208. for I := Length(ACode) downto 1 do
  1209. begin
  1210. if ACode[I] <> '-' then
  1211. Result := ACode[I] + Result
  1212. else
  1213. Break;
  1214. end;
  1215. if Result = '' then Result := '1';
  1216. end;
  1217. begin
  1218. if APreFixCode <> '' then
  1219. Result := APreFixCode + '-' + GetLastCode(AFullCode)
  1220. else
  1221. Result := GetLastcode(AFullCode);
  1222. end;
  1223. procedure TDMDataBase.ModifyCode(ANode: TZjIDTreeNode;
  1224. const APreCode, AOldCode: string; AIsCode: Boolean);
  1225. var
  1226. strPreCode, strOldCode: string;
  1227. begin
  1228. if cdsBills.FindKey([ANode.ID]) then
  1229. begin
  1230. if AIsCode and (cdsBillsB_Code.Value <> '') then Exit;
  1231. cdsBills.Edit;
  1232. if AIsCode then
  1233. begin
  1234. strOldCode := cdsBillsCode.AsString;
  1235. strPreCode := ReplaceCodePreFix(APreCode, strOldCode); //GetNewCode(strOldCode, AOldCode, APreCode);
  1236. cdsBillsCode.Value := strPreCode;
  1237. end
  1238. else
  1239. begin
  1240. strOldCode := cdsBillsB_Code.AsString;
  1241. strPreCode := ReplaceCodePreFix(APreCode, strOldCode); //GetNewCode(strOldCode, AOldCode, APreCode);
  1242. cdsBillsB_Code.Value := strPreCode;
  1243. end;
  1244. cdsBills.Post;
  1245. ChildCodeModifyByParent(ANode, strPreCode, strOldCode, AIsCode);
  1246. end;
  1247. end;
  1248. procedure TDMDataBase.cdsOrgBillsCodeChange(Sender: TField);
  1249. begin
  1250. Sender.Tag := 1;
  1251. end;
  1252. procedure TDMDataBase.cdsOrgBillsBeforeEdit(DataSet: TDataSet);
  1253. begin
  1254. FOldCode := cdsOrgBillsCode.Value;
  1255. FOldB_Code := cdsOrgBillsB_Code.Value;
  1256. Inc(FBillsUndoRef);
  1257. end;
  1258. procedure TDMDataBase.cdsOrgBillsAfterPost(DataSet: TDataSet);
  1259. var
  1260. ztnNode: TZjIDTreeNode;
  1261. begin
  1262. if cdsOrgBillsCode.Tag = 1 then
  1263. ModifyCodeIncludeChildren(FBillsTree.Selected, cdsOrgBillsCode.AsString, FOldCode, True);
  1264. if cdsOrgBillsB_Code.Tag = 1 then
  1265. ModifyCodeIncludeChildren(FBillsTree.Selected, cdsOrgBillsB_Code.AsString, FOldB_Code, False);
  1266. if cdsOrgBillsTotalPrice.Tag = 1 then
  1267. begin
  1268. ztnNode := FBillsTree.Selected;
  1269. if ztnNode <> nil then
  1270. begin
  1271. FEnabledUITreeEvt(False);
  1272. AscendSumToParent(ztnNode.Parent, FOldTotalPrice, cdsOrgBillsTotalPrice.AsFloat);
  1273. FEnabledUITreeEvt(True);
  1274. end;
  1275. cdsOrgBillsTotalPrice.Tag := 0;
  1276. end;
  1277. if cdsOrgBillsIsSuperscale.Tag = 1 then
  1278. begin
  1279. if cdsOrgBillsIsSuperscale.AsBoolean then
  1280. AddError(ecSuperscale, 1)
  1281. else
  1282. CancelError(ecSuperscale);
  1283. end;
  1284. if
  1285. (cdsOrgBillsCode.Tag = 1) or
  1286. (cdsOrgBillsB_Code.Tag = 1) or
  1287. (cdsOrgBillsName.Tag = 1) or
  1288. (cdsOrgBillsUnits.Tag = 1) or
  1289. (cdsOrgBillsQuantity.Tag = 1) or
  1290. (cdsOrgBillsDesignQuantity.Tag = 1) or
  1291. (cdsOrgBillsDesignQuantity2.Tag = 1) or
  1292. (cdsOrgBillsErrorHint.Tag = 1) or
  1293. (cdsOrgBillsIsSuperscale.Tag = 1) or
  1294. (cdsOrgBillsStandardGrade.Tag = 1) or
  1295. (cdsOrgBillsDeductGrade.Tag = 1) or
  1296. (cdsOrgBillsIsIgNore.Tag = 1) or
  1297. (cdsOrgBillsUserModified.Tag = 1) or
  1298. (cdsOrgBillsLostPreSiblingCount.Tag = 1) or
  1299. (cdsOrgBillsLostChildrenCount.Tag = 1) or
  1300. (cdsOrgBillsLostNextSiblingCount.Tag = 1) or
  1301. (cdsOrgBillsNameErrorFlag.Tag = 1) or
  1302. (cdsOrgBillsUnitsErrorFlag.Tag = 1) or
  1303. (cdsOrgBillsIsAccQuantity.Tag = 1) then
  1304. begin
  1305. if FNeedSyncTree then
  1306. SyncGradeFromDataSetToTreeNode(cdsOrgBills);
  1307. {ReGather Parent's DesignQuantity and DesignQuantity2}
  1308. if (cdsOrgBillsIsAccQuantity.Tag = 1) or (cdsOrgBillsDesignQuantity.Tag = 1) or
  1309. (cdsOrgBillsDesignQuantity2.Tag = 1) then
  1310. // 这个方法改为对父节点统计子节点的同时,其本身也统计自己的子节点数量
  1311. CalculateParentQuantity;
  1312. cdsOrgBillsCode.Tag := 0;
  1313. cdsOrgBillsB_Code.Tag := 0;
  1314. cdsOrgBillsName.Tag := 0;
  1315. cdsOrgBillsUnits.Tag := 0;
  1316. cdsOrgBillsQuantity.Tag := 0;
  1317. cdsOrgBillsDesignQuantity.Tag := 0;
  1318. cdsOrgBillsDesignQuantity2.Tag := 0;
  1319. cdsOrgBillsErrorHint.Tag := 0;
  1320. cdsOrgBillsIsSuperscale.Tag := 0;
  1321. cdsOrgBillsStandardGrade.Tag := 0;
  1322. cdsOrgBillsDeductGrade.Tag := 0;
  1323. cdsOrgBillsIsIgNore.Tag := 0;
  1324. cdsOrgBillsUserModified.Tag := 0;
  1325. cdsOrgBillsLostPreSiblingCount.Tag := 0;
  1326. cdsOrgBillsLostChildrenCount.Tag := 0;
  1327. cdsOrgBillsLostNextSiblingCount.Tag := 0;
  1328. cdsOrgBillsNameErrorFlag.Tag := 0;
  1329. cdsOrgBillsUnitsErrorFlag.Tag := 0;
  1330. cdsOrgBillsIsAccQuantity.Tag := 0;
  1331. end;
  1332. end;
  1333. procedure TDMDataBase.cdsOrgBillsAfterScroll(DataSet: TDataSet);
  1334. begin
  1335. if Assigned(FStdBillsCtrl) then
  1336. TStdBillsCtrl(FStdBillsCtrl).DMStdBillsLib.RefreshCustomStep;
  1337. if Assigned(FBillsTree.Selected) and Assigned(FDesignCodeEvt) then
  1338. begin
  1339. if FBillsTree.Selected.HasChildren then
  1340. FDesignCodeEvt(False)
  1341. else
  1342. FDesignCodeEvt(True);
  1343. end;
  1344. { if FIsProjectBills then
  1345. begin
  1346. Screen.Cursor := crHourGlass;
  1347. try
  1348. TDMDetailItems(FDetailItemsDM).RefreshPPItems;
  1349. finally
  1350. Screen.Cursor := crDefault;
  1351. end;
  1352. end; }
  1353. end;
  1354. {Note: this method only be used in before post}
  1355. procedure TDMDataBase.MatchCodeFromStdLib(const AName, AUnits: string);
  1356. begin
  1357. cdsOrgBillsName.Value := AName;
  1358. cdsOrgBillsUnits.Value := AUnits;
  1359. end;
  1360. procedure TDMDataBase.cdsOrgDrawingQuantityAfterPost(DataSet: TDataSet);
  1361. begin
  1362. // if FTriggerEvents then Exit;
  1363. if (cdsOrgDrawingQuantityIsGatherQ.Tag = 1) or (cdsOrgDrawingQuantityDQuantity1.Tag = 1) then
  1364. begin
  1365. GatherDQQty(cdsOrgBillsID.AsInteger, cdsOrgDrawingQuantityIsGatherQ.Tag = 1);
  1366. cdsOrgDrawingQuantityIsGatherQ.Tag := 0;
  1367. cdsOrgDrawingQuantityDQuantity1.Tag := 0;
  1368. end;
  1369. end;
  1370. procedure TDMDataBase.GatherDQQty(ABillsID: Integer; AGQ: Boolean);
  1371. var
  1372. sBillsUnit: string;
  1373. sDQUnit: string;
  1374. bChecked: Boolean;
  1375. function CalculateBillsQuantityFromDrawingItems: Double;
  1376. begin
  1377. Result := 0;
  1378. sBillsUnit := cdsBillsUnits.AsString;
  1379. bChecked := False;
  1380. cdsDQForLocate.SetRange([ABillsID], [ABillsID]);
  1381. try
  1382. while not cdsDQForLocate.Eof do
  1383. begin
  1384. if cdsDQForLocateIsGatherQ.Value then
  1385. begin
  1386. bChecked := True;
  1387. sDQUnit := cdsDQForLocateUnits.AsString;
  1388. if (UpperCase(sBillsUnit) = 'KG') and (UpperCase(sDQUnit) = 'T') then
  1389. Result := Result + 1000 * cdsDQForLocateDQuantity1.AsFloat
  1390. else if (UpperCase(sBillsUnit) = 'T') and (UpperCase(sDQUnit) = 'KG') then
  1391. Result := Result + cdsDQForLocateDQuantity1.AsFloat / 1000
  1392. else
  1393. Result := Result + cdsDQForLocateDQuantity1.AsFloat;
  1394. end;
  1395. cdsDQForLocate.Next;
  1396. end;
  1397. finally
  1398. cdsDQForLocate.CancelRange;
  1399. end;
  1400. end;
  1401. procedure UpdateBillsQuantity(AQuantity: Double);
  1402. begin
  1403. cdsBills.Edit;
  1404. cdsBillsQuantity.Value := AQuantity;
  1405. cdsBills.Post;
  1406. end;
  1407. function CanUpdateBillsQuantity: Boolean;
  1408. begin
  1409. Result := bChecked or AGQ;
  1410. end;
  1411. var
  1412. dTotalQty: Double;
  1413. begin
  1414. if not cdsBills.FindKey([ABillsID]) then Exit;
  1415. dTotalQty := CalculateBillsQuantityFromDrawingItems;
  1416. if CanUpdateBillsQuantity then
  1417. begin
  1418. UpdateBillsQuantity(dTotalQty);
  1419. FDMExprs.Delete(Exprs_Bills_ID, Exprs_Qty_ID, ABillsID);
  1420. end;
  1421. end;
  1422. procedure TDMDataBase.MatchCodeFromStdLib;
  1423. var
  1424. bIsCode: Boolean;
  1425. strCode, strName, strUnits: string;
  1426. begin
  1427. if cdsOrgBillsCode.Tag = 1 then
  1428. begin
  1429. strCode := cdsOrgBillsCode.Value;
  1430. bIsCode := True;
  1431. end
  1432. else if cdsOrgBillsB_Code.Tag = 1 then
  1433. begin
  1434. strCode := cdsOrgBillsB_Code.Value;
  1435. bIsCode := False;
  1436. end;
  1437. if TStdBillsCtrl(FStdBillsCtrl).DMStdBillsLib.FindLibCode(strCode, strName, strUnits, bIsCode) then
  1438. MatchCodeFromStdLib(strName, strUnits);
  1439. {refresh custom step when modify codes}
  1440. cdsOrgBills.AfterScroll(nil);
  1441. end;
  1442. procedure TDMDataBase.cdsOrgDrawingQuantityBeforePost(DataSet: TDataSet);
  1443. begin
  1444. if cdsOrgDrawingQuantityDQuantity1.Tag = 1 then
  1445. cdsOrgDrawingQuantityDQuantity1.Value := RoundTo(cdsOrgDrawingQuantityDQuantity1.Value, -3);
  1446. end;
  1447. procedure TDMDataBase.SetDecimalDigit;
  1448. begin
  1449. if cdsOrgBillsCode.AsString = '' then
  1450. begin
  1451. cdsOrgBillsDesignQuantity.Clear;
  1452. cdsOrgBillsDesignQuantity2.Clear;
  1453. cdsOrgBillsDesignPrice.Clear;
  1454. {if is gather node, then can not input value}
  1455. if IsGatherNode then
  1456. begin
  1457. cdsOrgBillsQuantity.Clear;
  1458. cdsOrgBillsUnitPrice.Clear;
  1459. end
  1460. else
  1461. begin
  1462. if cdsOrgBillsQuantity.Tag = 1 then
  1463. cdsOrgBillsQuantity.Value := ScRoundTo(cdsOrgBillsQuantity.Value, -3);
  1464. if cdsOrgBillsUnitPrice.Tag = 1 then
  1465. cdsOrgBillsUnitPrice.Value := ScRoundTo(cdsOrgBillsUnitPrice.Value, -3);
  1466. if (cdsOrgBillsQuantity.Tag = 1) or (cdsOrgBillsUnitPrice.Tag = 1) then
  1467. begin
  1468. if ScConfigInfo.RealTimeCalc then
  1469. begin
  1470. FOldTotalPrice := cdsOrgBillsTotalPrice.AsFloat;
  1471. cdsOrgBillsTotalPrice.Value := ScRoundTo(cdsOrgBillsQuantity.AsFloat * cdsOrgBillsUnitPrice.AsFloat, 0);
  1472. end;
  1473. end;
  1474. end;
  1475. end
  1476. else
  1477. begin
  1478. cdsOrgBillsQuantity.Clear;
  1479. cdsOrgBillsUnitPrice.Clear;
  1480. if cdsOrgBillsDesignQuantity.Tag = 1 then
  1481. cdsOrgBillsDesignQuantity.Value := ScRoundTo(cdsOrgBillsDesignQuantity.Value, -3);
  1482. if cdsOrgBillsDesignQuantity2.Tag = 1 then
  1483. cdsOrgBillsDesignQuantity2.Value := ScRoundTo(cdsOrgBillsDesignQuantity2.Value, -3);
  1484. if cdsOrgBillsDesignPrice.Tag = 1 then
  1485. cdsOrgBillsDesignPrice.Value := ScRoundTo(cdsOrgBillsDesignPrice.Value, -3);
  1486. if (cdsOrgBillsDesignQuantity.Tag = 1) then
  1487. begin
  1488. if ScConfigInfo.RealTimeCalc then
  1489. begin
  1490. if cdsOrgBillsDesignQuantity.AsFloat <> 0 then
  1491. cdsOrgBillsDesignPrice.Value := ScRoundTo(cdsOrgBillsTotalPrice.AsFloat/cdsOrgBillsDesignQuantity.AsFloat, -2)
  1492. else
  1493. cdsOrgBillsDesignPrice.Value := 0;
  1494. //FOldTotalPrice := cdsOrgBillsTotalPrice.AsFloat;
  1495. //cdsOrgBillsTotalPrice.Value := ScRoundTo(cdsOrgBillsDesignQuantity.AsFloat * cdsOrgBillsDesignPrice.AsFloat, 0);
  1496. end;
  1497. end;
  1498. end;
  1499. // Litao 2011.4.22
  1500. // cdsOrgBillsDesignQuantity.Tag := 0;
  1501. // cdsOrgBillsDesignQuantity2.Tag := 0;
  1502. // cdsOrgBillsDesignPrice.Tag := 0;
  1503. // cdsOrgBillsQuantity.Tag := 0;
  1504. // cdsOrgBillsUnitPrice.Tag := 0;
  1505. // chenshilong, 2011-06-17 18:20:22
  1506. // 以上这些被注释。AfterPost事件需要用这些标记来同步清单评分树。
  1507. end;
  1508. procedure TDMDataBase.ClearAllQuantity(ANode: TZjIDTreeNode);
  1509. var
  1510. I: Integer;
  1511. vNode: TZjIDTreeNode;
  1512. begin
  1513. ClearBillsQuantity(ANode.ID);
  1514. for I := 0 to ANode.ChildCount - 1 do
  1515. begin
  1516. vNode := ANode.ChildNodes[I];
  1517. ClearAllQuantity(vNode);
  1518. end;
  1519. end;
  1520. procedure TDMDataBase.ClearDQQuantity(const ABillsID: Integer);
  1521. begin
  1522. cdsDQForLocate.SetRange([ABillsID], [ABillsID]);
  1523. while not cdsDQForLocate.Eof do
  1524. begin
  1525. cdsDQForLocate.Edit;
  1526. cdsDQForLocateDQuantity1.Value := 0;
  1527. cdsDQForLocate.Post;
  1528. cdsDQForLocate.Next;
  1529. end;
  1530. cdsDQForLocate.CancelRange;
  1531. end;
  1532. procedure TDMDataBase.ClearBillsQuantity(const ABillsID: Integer);
  1533. begin
  1534. if cdsBills.FindKey([ABillsID]) then
  1535. begin
  1536. cdsBills.Edit;
  1537. if cdsBillsCode.Value = '' then
  1538. begin
  1539. if IsGatherNode(ABillsID) then
  1540. cdsBillsQuantity.Clear
  1541. else
  1542. cdsBillsQuantity.Value := 0;
  1543. // cdsBillsUnitPrice.Value := 0;
  1544. end
  1545. else
  1546. begin
  1547. cdsBillsDesignQuantity.Value := 0;
  1548. cdsBillsDesignQuantity2.Value := 0;
  1549. // cdsBillsDesignPrice.Value := 0;
  1550. end;
  1551. cdsBills.Post;
  1552. ClearDQQuantity(ABillsID);
  1553. end;
  1554. end;
  1555. procedure TDMDataBase.ClearCurNodeQty;
  1556. begin
  1557. if Boolean(FBillsTree.Selected) then
  1558. begin
  1559. FEnabledUITreeEvt(False);
  1560. ClearAllQuantity(FBillsTree.Selected);
  1561. FEnabledUITreeEvt(True);
  1562. end;
  1563. end;
  1564. function TDMDataBase.IsGatherNode: Boolean;
  1565. begin
  1566. Result := Assigned(FBillsTree.Selected) and FBillsTree.Selected.HasChildren
  1567. and (FBillsTree.Selected.ID = cdsOrgBillsID.Value)
  1568. and (cdsOrgBillsCode.Value = '');
  1569. end;
  1570. procedure TDMDataBase.ShowLevel(aLevelID: Integer);
  1571. begin
  1572. FBillsTree.ExpandLevel := aLevelID;
  1573. end;
  1574. procedure TDMDataBase.GetChapterNames(ANames: TStrings);
  1575. var
  1576. I, iID: Integer;
  1577. strName: string;
  1578. begin
  1579. if not Assigned(ANames) then Exit;
  1580. ANames.Clear;
  1581. with FBillsTree.FirstNode do
  1582. begin
  1583. for I := 0 to ChildCount - 1 do
  1584. begin
  1585. iID := ChildNodes[I].ID;
  1586. if cdsBills.FindKey([iID]) then
  1587. begin
  1588. strName := Format('%s %s', [cdsBillsCode.Value, cdsBillsName.Value]);
  1589. ANames.AddObject(strName, TObject(Pointer(iID)));
  1590. end;
  1591. end;
  1592. end;
  1593. end;
  1594. procedure TDMDataBase.LocateBills(aBillsID: Integer);
  1595. begin
  1596. FEnabledUITreeEvt(False);
  1597. try
  1598. cdsOrgBills.FindKey([aBillsID]);
  1599. finally
  1600. FEnabledUITreeEvt(True);
  1601. end;
  1602. end;
  1603. type
  1604. TFieldAccess = class(TField);
  1605. // 功能: 当参数DisplayText=True 时返回字段的文本串
  1606. // 当参数DisplayText=False 时返回字段的对应的公式,如果没有公式则返回文本值
  1607. // 说明:
  1608. // 当界面通过Field的DisplayText和Text属性访问字段的内容时会触发该事件。
  1609. // 1. 当要显示编辑状态的文本时Field.Text被调用,此时参数DisplayText=False
  1610. // 2. 当要显示非编辑状态的文本时Field.DisplayText被调用, 此时参数DisplayText=True;
  1611. procedure TDMDataBase.cdsOrgBillsQuantityGetText(Sender: TField;
  1612. var Text: String; DisplayText: Boolean);
  1613. var
  1614. iFieldID: Integer;
  1615. begin
  1616. if DisplayText then
  1617. begin
  1618. TFieldAccess(Sender).GetText(Text, DisplayText);
  1619. if Text = '0' then Text := '';
  1620. { if BillsTree[cdsBillsID.Value].HasChildren and (Sender <> cdsBillsTotalPrice) and (Sender <> cdsBillsQuantity) then
  1621. begin
  1622. Text := '';
  1623. end;}
  1624. end
  1625. else
  1626. begin
  1627. // 查找公式,公式字符串保存在表cdsExprs中,根据三个字段唯一标示一个公式,
  1628. // 这三个字段是:拥有该公式的 表的ID、字段ID、记录ID;
  1629. iFieldID := 0;
  1630. if Sender = cdsOrgBillsQuantity then
  1631. iFieldID := 1
  1632. else if Sender = cdsOrgBillsDesignQuantity then
  1633. iFieldID := 2
  1634. else if Sender = cdsOrgBillsDesignQuantity2 then
  1635. iFieldID := 3;
  1636. Text := FDMExprs.GetExprs(Exprs_Bills_ID, iFieldID, cdsOrgBillsID.Value);
  1637. if Text = '' then TFieldAccess(Sender).GetText(Text, DisplayText);
  1638. end;
  1639. end;
  1640. procedure TDMDataBase.cdsOrgBillsQuantitySetText(Sender: TField;
  1641. const Text: String);
  1642. var
  1643. fValue: Double;
  1644. iCode, iLocation, iFieldID: Integer;
  1645. begin
  1646. iFieldID := 0;
  1647. if Sender = cdsOrgBillsQuantity then
  1648. iFieldID := Exprs_Qty_ID
  1649. else if Sender = cdsOrgBillsDesignQuantity then
  1650. iFieldID := Exprs_DQty_ID
  1651. else if Sender = cdsOrgBillsDesignQuantity2 then
  1652. iFieldID := Exprs_DQty2_ID;
  1653. if Trim(Text) = '' then
  1654. begin
  1655. Sender.AsString := Text;
  1656. FDMExprs.Delete(Exprs_Bills_ID, iFieldID, cdsOrgBillsID.Value);
  1657. end
  1658. else
  1659. begin
  1660. Val(Text, fValue, iCode);
  1661. if iCode <> 0 then
  1662. begin
  1663. fValue := Evaluate(Text, iCode, iLocation);
  1664. FDMExprs.AddExprs(Exprs_Bills_ID, iFieldID, cdsOrgBillsID.Value, Text, fValue, iCode);
  1665. end
  1666. else
  1667. FDMExprs.Delete(Exprs_Bills_ID, iFieldID, cdsOrgBillsID.Value);
  1668. if iCode <> 0 then
  1669. raise EBitsError.Create('输入的计算式不正确!');
  1670. Sender.AsFloat := fValue;
  1671. end;
  1672. end;
  1673. procedure TDMDataBase.cdsOrgDrawingQuantityDQuantity1GetText(
  1674. Sender: TField; var Text: String; DisplayText: Boolean);
  1675. var
  1676. iFieldID: Integer;
  1677. begin
  1678. if DisplayText then
  1679. begin
  1680. TFieldAccess(Sender).GetText(Text, DisplayText);
  1681. end
  1682. else
  1683. begin
  1684. // 查找公式,公式字符串保存在表cdsExprs中,根据三个字段唯一标示一个公式,
  1685. // 这三个字段是:拥有该公式的 表的ID、字段ID、记录ID;
  1686. iFieldID := 0;
  1687. if (Sender = cdsOrgDrawingQuantityDQuantity1) then
  1688. iFieldID := Exprs_DQty_ID;
  1689. if Sender = cdsOrgDrawingQuantityDQuantity1 then
  1690. Text := FDMExprs.GetExprs(Exprs_DrawQty_ID, iFieldID, cdsOrgDrawingQuantityID.Value);
  1691. if Text = '' then TFieldAccess(Sender).GetText(Text, DisplayText);
  1692. end;
  1693. end;
  1694. procedure TDMDataBase.cdsOrgDrawingQuantityDQuantity1SetText(
  1695. Sender: TField; const Text: String);
  1696. var
  1697. fValue: Double;
  1698. iCode, iLocation, iFieldID: Integer;
  1699. begin
  1700. iFieldID := 0;
  1701. if (Sender = cdsOrgDrawingQuantityDQuantity1) then
  1702. iFieldID := Exprs_DQty_ID;
  1703. if Trim(Text) = '' then
  1704. begin
  1705. Sender.AsString := Text;
  1706. if Sender = cdsOrgDrawingQuantityDQuantity1 then
  1707. FDMExprs.Delete(Exprs_DrawQty_ID, iFieldID, cdsOrgDrawingQuantityID.Value);
  1708. end
  1709. else
  1710. begin
  1711. Val(Text, fValue, iCode);
  1712. if iCode <> 0 then
  1713. begin
  1714. fValue := Evaluate(Text, iCode, iLocation);
  1715. if Sender = cdsOrgDrawingQuantityDQuantity1 then
  1716. FDMExprs.AddExprs(Exprs_DrawQty_ID, iFieldID, cdsOrgDrawingQuantityID.Value, Text, fValue, iCode);
  1717. end
  1718. else
  1719. begin
  1720. if Sender = cdsOrgDrawingQuantityDQuantity1 then
  1721. FDMExprs.Delete(Exprs_DrawQty_ID, iFieldID, cdsOrgDrawingQuantityID.Value);
  1722. end;
  1723. if iCode <> 0 then
  1724. raise EBitsError.Create('输入的计算式不正确!' + #13#10);
  1725. Sender.AsFloat := fValue;
  1726. end;
  1727. end;
  1728. procedure TDMDataBase.cdsOrgDrawingQuantityBeforeDelete(DataSet: TDataSet);
  1729. begin
  1730. // Added by GiLi 2012-3-19 11:13:43
  1731. // 记录当前删除项是否填工程量
  1732. FCurIsGatherQ := cdsOrgDrawingQuantityIsGatherQ.AsBoolean;
  1733. FBillsUndoRef := 0;
  1734. FDMExprs.Delete(Exprs_DrawQty_ID, cdsOrgDrawingQuantityID.AsInteger);
  1735. end;
  1736. procedure TDMDataBase.SyncBillsItemCode(const aID: Integer; const aCode,
  1737. aB_Code, aName: string);
  1738. var
  1739. vItem: TScBillsItem;
  1740. begin
  1741. vItem := FBillsTree[aID];
  1742. if Assigned(vItem) then
  1743. begin
  1744. vItem.SBillCode := aCode;
  1745. vItem.SBillBCode := aB_Code;
  1746. vItem.SBillName := aName;
  1747. end;
  1748. end;
  1749. procedure TDMDataBase.cdsBillsAfterPost(DataSet: TDataSet);
  1750. begin
  1751. if (cdsBillsCode.Tag = 1) or (cdsBillsB_Code.Tag = 1)
  1752. or (cdsBillsName.Tag = 1) then
  1753. begin
  1754. SyncBillsItemCode(cdsBillsID.Value, cdsBillsCode.Value,
  1755. cdsBillsB_Code.Value, cdsBillsName.Value);
  1756. cdsBillsCode.Tag := 0;
  1757. cdsBillsB_Code.Tag := 0;
  1758. cdsBillsName.Tag := 0;
  1759. end;
  1760. if (cdsBillsErrorHint.Tag = 1) or
  1761. (cdsBillsIsSuperscale.Tag = 1) or
  1762. (cdsBillsStandardGrade.Tag = 1) or
  1763. (cdsBillsDeductGrade.Tag = 1) or
  1764. (cdsBillsIsIgNore.Tag = 1) or
  1765. (cdsBillsUserModified.Tag = 1) or
  1766. (cdsBillsLostPreSiblingCount.Tag = 1) or
  1767. (cdsBillsLostChildrenCount.Tag = 1) or
  1768. (cdsBillsLostNextSiblingCount.Tag = 1) or
  1769. (cdsBillsNameErrorFlag.Tag = 1) or
  1770. (cdsBillsUnitsErrorFlag.Tag = 1) then
  1771. begin
  1772. if FNeedSyncTree then
  1773. SyncGradeFromDataSetToTreeNode(cdsBills);
  1774. cdsBillsErrorHint.Tag := 0;
  1775. cdsBillsIsSuperscale.Tag := 0;
  1776. cdsBillsStandardGrade.Tag := 0;
  1777. cdsBillsDeductGrade.Tag := 0;
  1778. cdsBillsIsIgNore.Tag := 0;
  1779. cdsBillsUserModified.Tag := 0;
  1780. cdsBillsLostPreSiblingCount.Tag := 0;
  1781. cdsBillsLostChildrenCount.Tag := 0;
  1782. cdsBillsLostNextSiblingCount.Tag := 0;
  1783. cdsBillsNameErrorFlag.Tag := 0;
  1784. cdsBillsUnitsErrorFlag.Tag := 0;
  1785. end;
  1786. end;
  1787. function TDMDataBase.IsGatherNode(const aID: Integer): Boolean;
  1788. var
  1789. vItem: TScBillsItem;
  1790. begin
  1791. Result := False;
  1792. vItem := FBillsTree[aID];
  1793. if Assigned(vItem) and vItem.HasChildren then
  1794. Result := True;
  1795. end;
  1796. procedure TDMDataBase.OnlyShowXMJ;
  1797. var
  1798. ztnFirstNode: TZjIDTreeNode;
  1799. begin
  1800. ztnFirstNode := FBillsTree.FirstNode;
  1801. if Assigned(ztnFirstNode) then
  1802. FilterXMJ(ztnFirstNode);
  1803. end;
  1804. procedure TDMDataBase.FilterXMJ(aNode: TZjIDTreeNode);
  1805. var
  1806. I: Integer;
  1807. begin
  1808. if not aNode.HasChildren then Exit;
  1809. if HasXMJ(aNode) then
  1810. begin
  1811. if not aNode.Expanded then
  1812. aNode.Expand;
  1813. for I := 0 to aNode.ChildCount - 1 do
  1814. FilterXMJ(aNode.ChildNodes[I]);
  1815. end
  1816. else
  1817. if aNode.Expanded then
  1818. aNode.Collapse;
  1819. end;
  1820. procedure TDMDataBase.DeleteBills(aIDList: TStringList;
  1821. aPreID, aLastID, aParentID: Integer);
  1822. var
  1823. I, iID: Integer;
  1824. iMajorIdx, iCount: Integer;
  1825. IDLstString: string;
  1826. cdsDataSet: TClientDataSet;
  1827. begin
  1828. iID := StrToInt(aIDList.Strings[0]);
  1829. BeforeDelete(iID, iMajorIdx);
  1830. try
  1831. iCount := 0;
  1832. for I := 1 to aIDList.Count - 1 do
  1833. begin
  1834. IDLstString := aIDList.Strings[I];
  1835. cdsDataSet := TClientDataSet.Create(nil);
  1836. cdsDataSet.CloneCursor(cdsBills, True);
  1837. try
  1838. cdsDataSet.Filter := IDLstString;
  1839. cdsDataSet.Filtered := True;
  1840. cdsDataSet.First;
  1841. while not cdsDataSet.Eof do
  1842. begin
  1843. DeleteDQ(cdsDataSet.FieldByName(SID).AsInteger);
  1844. FDMExprs.Delete(Exprs_Bills_ID, cdsDataSet.FieldByName(SID).AsInteger);
  1845. Inc(iCount);
  1846. cdsDataSet.Delete;
  1847. end;
  1848. finally
  1849. cdsDataSet.Free;
  1850. end;
  1851. end;
  1852. finally
  1853. AfterDelete(iMajorIdx, iCount, aParentID, aPreID, aLastID);
  1854. FBillsUndoRef := 0;
  1855. FDrawQtyUndoRef := 0;
  1856. end;
  1857. end;
  1858. procedure TDMDataBase.ReadStatus(AID, ALength: Integer);
  1859. procedure InnerRead(ANode: TZjIDTreeNode);
  1860. var
  1861. ID: Integer;
  1862. begin
  1863. ID := FSelList[ANode.MajorIndex];
  1864. if ID = 0 then
  1865. begin
  1866. ANode.Expand;
  1867. if ANode.HasChildren then
  1868. InnerRead(ANode.FirstChild);
  1869. if Assigned(ANode.NextSibling) then
  1870. InnerRead(ANode.NextSibling);
  1871. end
  1872. else if ID = -1 then
  1873. begin
  1874. if Assigned(ANode.NextSibling) then
  1875. InnerRead(ANode.NextSibling);
  1876. Exit;
  1877. end
  1878. else
  1879. begin
  1880. ANode.Collapse;
  1881. ANode := ANode.NextSibling;
  1882. if Assigned(ANode) then
  1883. InnerRead(ANode);
  1884. end;
  1885. end;
  1886. begin
  1887. if AID > -1 then
  1888. begin
  1889. if ALength > 0 then // 增加
  1890. while ALength > 0 do
  1891. begin
  1892. FSelList.Insert(AID + 1, Pointer(-1));
  1893. Dec(ALength);
  1894. end
  1895. else // 删除
  1896. while ALength < 0 do
  1897. begin
  1898. FSelList.Delete(AID + 1);
  1899. Inc(ALength);
  1900. end;
  1901. end;
  1902. if FBillsTree.FirstNode <> nil then
  1903. InnerRead(FBillsTree.FirstNode);
  1904. end;
  1905. procedure TDMDataBase.SaveStatus;
  1906. {展开为0, 收缩为1}
  1907. procedure InnerSave(ANode: TZjIDTreeNode);
  1908. begin
  1909. if ANode.Expanded then
  1910. FSelList[ANode.MajorIndex] := 0
  1911. else FSelList[ANode.MajorIndex] := 1;
  1912. if ANode.HasChildren then
  1913. InnerSave(ANode.FirstChild);
  1914. if Assigned(ANode.NextSibling) then
  1915. InnerSave(ANode.NextSibling);
  1916. end;
  1917. begin
  1918. FSelList.Clear;
  1919. InnerSave(FBillsTree.FirstNode);
  1920. end;
  1921. function TDMDataBase.HasXMJ(aNode: TZjIDTreeNode): Boolean;
  1922. begin
  1923. Result := False;
  1924. if (TScBillsItem(aNode.FirstChild).SBillCode <> '') then
  1925. Result := True;
  1926. end;
  1927. procedure TDMDataBase.DeleteBills(aID: Integer);
  1928. begin
  1929. if cdsBills.FindKey([aID]) then cdsBills.Delete;
  1930. end;
  1931. procedure TDMDataBase.ConnectionBillsTree;
  1932. begin
  1933. try
  1934. FBillsTree.DataSet := cdsOrgBills;
  1935. BeginEvents;
  1936. try
  1937. FBillsTree.Active := True;
  1938. finally
  1939. EndEvents;
  1940. end;
  1941. except
  1942. SetSavePoint(FSavePoint);
  1943. ConnectionBillsTree;
  1944. end;
  1945. end;
  1946. procedure TDMDataBase.DisconnectBillsTree;
  1947. begin
  1948. FSavePoint := GetSavePoint;
  1949. FBillsTree.DataSet := nil;
  1950. FBillsTree.Active := False;
  1951. end;
  1952. procedure TDMDataBase.ModifyCodeIncludeChildren(ANode: TZjIDTreeNode;
  1953. const APreCode, AOldCode: string; AIsCode: Boolean);
  1954. {var
  1955. iCurID: Integer;}
  1956. begin
  1957. // iCurID := ANode.ID;
  1958. FEnabledUITreeEvt(False);
  1959. { ***************************************************
  1960. Method2:
  1961. Note: this way can not refresh the billstree's structure,
  1962. so it can not be used in copybills method
  1963. *****************************************************}
  1964. // cdsOrgBills.Active := False;
  1965. ChildCodeModifyByParent(ANode, APreCode, AOldCode, AIsCode);
  1966. // cdsOrgBills.CloneCursor(cdsBills, True);
  1967. // FBillsTree[iCurID].LocateDBRecord;
  1968. FEnabledUITreeEvt(True);
  1969. end;
  1970. procedure TDMDataBase.WriteRecIntoDB(aList: TList);
  1971. var
  1972. I: Integer;
  1973. billRec: TBillIDRecord;
  1974. begin
  1975. for I := 0 to aList.Count - 1 do
  1976. begin
  1977. billRec := TBillIDRecord(aList[I]);
  1978. cdsBills.Insert;
  1979. cdsBillsID.Value := billRec.NewID;
  1980. cdsBillsParentID.Value := billRec.ParentID;
  1981. cdsBillsNextSiblingID.Value := billRec.NextSiblingID;
  1982. cdsBillsCode.Value := billRec.Code;
  1983. cdsBillsName.Value := billRec.Name;
  1984. cdsBillsUnits.Value := billRec.Units;
  1985. if SameText(billRec.Code, '') then
  1986. begin
  1987. cdsBillsQuantity.Value := billRec.Quantity;
  1988. cdsBillsUnitPrice.Value := billRec.UnitPrice;
  1989. end
  1990. else
  1991. begin
  1992. cdsBillsDesignQuantity.Value := billRec.DesignQuantity;
  1993. cdsBillsDesignQuantity2.Value := billRec.DesignQuantity2;
  1994. cdsBillsDesignPrice.Value := billRec.DesignPrice;
  1995. end;
  1996. cdsBillsB_Code.Value := billRec.B_Code;
  1997. cdsBillsTotalPrice.Value := billRec.TotalPrice;
  1998. cdsBillsMemoStr.Value := billRec.MemoStr;
  1999. cdsBills.Post;
  2000. end;
  2001. end;
  2002. procedure TDMDataBase.BeginEvents(aExceptInsert: Boolean);
  2003. begin
  2004. FBillsAfterInsertEvt := cdsOrgBills.AfterInsert;
  2005. FBillsBeforePostEvt := cdsOrgBills.BeforePost;
  2006. FBillsBeforeEditEvt := cdsOrgBills.BeforeEdit;
  2007. FBillsAfterPostEvt := cdsOrgBills.AfterPost;
  2008. FBillsAfterScrollEvt := cdsOrgBills.AfterScroll;
  2009. if not aExceptInsert then
  2010. cdsOrgBills.AfterInsert := nil;
  2011. cdsOrgBills.BeforePost := nil;
  2012. cdsOrgBills.BeforeEdit := nil;
  2013. cdsOrgBills.AfterPost := nil;
  2014. cdsOrgBills.AfterScroll := nil;
  2015. end;
  2016. procedure TDMDataBase.EndEvents;
  2017. begin
  2018. cdsOrgBills.AfterInsert := FBillsAfterInsertEvt;
  2019. cdsOrgBills.BeforePost := FBillsBeforePostEvt;
  2020. cdsOrgBills.BeforeEdit := FBillsBeforeEditEvt;
  2021. cdsOrgBills.AfterPost := FBillsAfterPostEvt;
  2022. cdsOrgBills.AfterScroll := FBillsAfterScrollEvt;
  2023. end;
  2024. function TDMDataBase.ModifyNextSiblingID(aID, aNewNextID: Integer;
  2025. var aParentID, aNextID: Integer): Boolean;
  2026. begin
  2027. Result := True;
  2028. if cdsBills.FindKey([aID]) then
  2029. begin
  2030. aParentID := cdsBillsParentID.Value;
  2031. aNextID := cdsBillsNextSiblingID.Value;
  2032. cdsBills.Edit;
  2033. cdsBillsNextSiblingID.Value := aNewNextID;
  2034. cdsBills.Post;
  2035. end
  2036. else Result := False;
  2037. end;
  2038. function TDMDataBase.GetSavePoint: Integer;
  2039. begin
  2040. Result := cdsBills.SavePoint;
  2041. end;
  2042. procedure TDMDataBase.SetSavePoint(aSavePoint: Integer);
  2043. begin
  2044. cdsBills.SavePoint := aSavePoint;
  2045. end;
  2046. procedure TDMDataBase.ModifySelected(aID: Integer; aValue: Boolean);
  2047. begin
  2048. if cdsBills.FindKey([aID]) then
  2049. begin
  2050. cdsBills.Edit;
  2051. cdsBillsSelected.Value := aValue;
  2052. cdsBills.Post;
  2053. end;
  2054. end;
  2055. // 删除第一部分与第二部分的清单为数量单价为0项
  2056. procedure TDMDataBase.RemoveZeroQtyBills;
  2057. var
  2058. lstItems, lstIDs: TList;
  2059. begin
  2060. lstItems := TList.Create;
  2061. lstIDs := TList.Create;
  2062. try
  2063. // 删除第一部分的清单为数量单价为0项
  2064. FilterZeroQtyBills(lstItems, lstIDs, FBillsTree.FirstNode);
  2065. // 删除第二部分的清单为数量单价为0项
  2066. FilterZeroQtyBills(lstItems, lstIDs, FBillsTree.FirstNode.NextSibling);
  2067. FEnabledUITreeEvt(False);
  2068. DisconnectBillsTree;
  2069. try
  2070. UpdateRecords(lstItems);
  2071. RemoveRecords(lstIDs);
  2072. finally
  2073. ConnectionBillsTree;
  2074. FEnabledUITreeEvt(True);
  2075. end;
  2076. finally
  2077. ClearList(lstItems);
  2078. lstItems.Free;
  2079. lstIDs.Free;
  2080. end;
  2081. end;
  2082. procedure TDMDataBase.FilterZeroQtyBills(aItems, aIDs: TList;
  2083. aNode: TZjIDTreeNode);
  2084. var
  2085. I: Integer;
  2086. rIDRecord: PIDRecord;
  2087. childNode: TZjIDTreeNode;
  2088. begin
  2089. for I := 0 to aNode.ChildCount - 1 do
  2090. begin
  2091. childNode := aNode.ChildNodes[I];
  2092. if CanRemove(childNode) then
  2093. begin
  2094. if Assigned(childNode.PrevSibling) then
  2095. begin
  2096. rIDRecord := FindIDRecord(aItems, childNode.ID);
  2097. if rIDRecord = nil then
  2098. begin
  2099. New(rIDRecord);
  2100. rIDRecord.PreID := childNode.PrevSiblingID;
  2101. rIDRecord.NextID := childNode.NextSiblingID;
  2102. aItems.Add(rIDRecord);
  2103. end
  2104. else
  2105. rIDRecord.NextID := childNode.NextSiblingID;
  2106. end;
  2107. FilterRemoveIDs(childNode, aIDs);
  2108. end
  2109. else
  2110. FilterZeroQtyBills(aItems, aIDs, childNode);
  2111. end;
  2112. end;
  2113. procedure TDMDataBase.RemoveRecords(aIDs: TList);
  2114. var
  2115. I, iCount: Integer;
  2116. strIDs: string;
  2117. begin
  2118. iCount := 0;
  2119. for I := 0 to aIDs.Count - 1 do
  2120. begin
  2121. if strIDs = '' then
  2122. strIDs := 'ID=' + IntToStr(Integer(aIDs.List^[I]))
  2123. else
  2124. strIDs := strIDs + ' or ID=' + IntToStr(Integer(aIDs.List^[I]));
  2125. Inc(iCount);
  2126. if I < aIDs.Count - 1 then
  2127. begin
  2128. if iCount > 500 then
  2129. begin
  2130. RemoveRecords(strIDs);
  2131. strIDs := '';
  2132. iCount := 0;
  2133. end;
  2134. Continue;
  2135. end;
  2136. RemoveRecords(strIDs);
  2137. end;
  2138. end;
  2139. procedure TDMDataBase.UpdateRecords(aList: TList);
  2140. var
  2141. I: Integer;
  2142. rIDRecord: PIDRecord;
  2143. begin
  2144. for I := 0 to aList.Count - 1 do
  2145. begin
  2146. rIDRecord := aList.List^[I];
  2147. UpdateRecord(rIDRecord.PreID, rIDRecord.NextID);
  2148. end;
  2149. end;
  2150. procedure TDMDataBase.UpdateRecord(aPreID, aNextID: Integer);
  2151. begin
  2152. if cdsBills.FindKey([aPreID]) then
  2153. begin
  2154. cdsBills.Edit;
  2155. cdsBillsNextSiblingID.Value := aNextID;
  2156. cdsBills.Post;
  2157. end;
  2158. end;
  2159. function TDMDataBase.CanRemove(aNode: TZjIDTreeNode): Boolean;
  2160. var
  2161. I: Integer;
  2162. chdNode: TZjIDTreeNode;
  2163. begin
  2164. if IsQuantityZero(aNode.ID) then
  2165. Result := True
  2166. else
  2167. begin
  2168. Result := False;
  2169. Exit;
  2170. end;
  2171. for I := 0 to aNode.ChildCount - 1 do
  2172. begin
  2173. chdNode := aNode.ChildNodes[I];
  2174. if not CanRemove(chdNode) then
  2175. begin
  2176. Result := False;
  2177. Break;
  2178. end;
  2179. end;
  2180. end;
  2181. function TDMDataBase.IsQuantityZero(aID: Integer): Boolean;
  2182. begin
  2183. Result := True;
  2184. if cdsBills.FindKey([aID]) then
  2185. begin
  2186. Result := (cdsBillsQuantity.Value = 0) and (cdsBillsDesignQuantity.Value = 0)
  2187. and (cdsBillsDesignQuantity2.Value = 0) and (cdsBillsUnitPrice.Value = 0);
  2188. end;
  2189. end;
  2190. procedure TDMDataBase.FilterRemoveIDs(aNode: TZjIDTreeNode;
  2191. aIDs: TList);
  2192. var
  2193. I: Integer;
  2194. chdNode: TZjIDTreeNode;
  2195. begin
  2196. aIDs.Add(Pointer(aNode.ID));
  2197. for I := 0 to aNode.ChildCount - 1 do
  2198. begin
  2199. chdNode := aNode.ChildNodes[I];
  2200. FilterRemoveIDs(chdNode, aIDs);
  2201. end;
  2202. end;
  2203. procedure TDMDataBase.ClearList(aList: TList);
  2204. var
  2205. I: Integer;
  2206. begin
  2207. for I := 0 to aList.Count - 1 do
  2208. Dispose(aList.List^[I]);
  2209. aList.Clear;
  2210. end;
  2211. procedure TDMDataBase.RemoveRecords(aIDs: string);
  2212. var
  2213. cdsTempData: TClientDataSet;
  2214. begin
  2215. cdsTempData := TClientDataSet.Create(nil);
  2216. try
  2217. cdsTempData.CloneCursor(cdsBills, True);
  2218. cdsTempData.Filter := aIDs;
  2219. cdsTempData.Filtered := True; {set filtered will set cursor to the first record}
  2220. while not cdsTempData.Eof do
  2221. begin
  2222. DeleteDQ(cdsTempData.FieldByName(SID).AsInteger);
  2223. FDMExprs.Delete(Exprs_Bills_ID, cdsTempData.FieldByName(SID).AsInteger);
  2224. cdsTempData.Delete;
  2225. end;
  2226. finally
  2227. cdsTempData.Free;
  2228. end;
  2229. end;
  2230. procedure TDMDataBase.AfterDelete(aMajorIdx, aCount, aParentID, aPreID, aLastID: Integer);
  2231. var
  2232. curNode: TScIDTreeNode;
  2233. begin
  2234. ModifyNextSiblingID(aPreID, aLastID);
  2235. ConnectionBillsTree;
  2236. ReadStatus(aMajorIdx, -aCount);
  2237. FEnabledUITreeEvt(True);
  2238. cdsOrgDrawingQuantity.EnableControls;
  2239. if aLastID <> -1 then
  2240. begin
  2241. curNode := FBillsTree.FindNode(ALastID);
  2242. if Assigned(curNode) then curNode.LocateDBRecord;
  2243. end
  2244. else if aPreID <> -1 then
  2245. begin
  2246. curNode := FBillsTree.FindNode(APreID);
  2247. if Assigned(curNode) then curNode.LocateDBRecord;
  2248. end
  2249. else if aParentID <> -1 then
  2250. begin
  2251. curNode := FBillsTree.FindNode(aParentID);
  2252. if Assigned(curNode) then curNode.LocateDBRecord;
  2253. end;
  2254. end;
  2255. procedure TDMDataBase.BeforeDelete(aID: Integer; var aMajorIdx: Integer);
  2256. var
  2257. curNode: TZjIDTreeNode;
  2258. begin
  2259. cdsOrgDrawingQuantity.DisableControls;
  2260. FEnabledUITreeEvt(False);
  2261. SaveStatus;
  2262. curNode := FBillsTree.BillsItem[aID];
  2263. aMajorIdx := curNode.PrevNode.MajorIndex;
  2264. DisconnectBillsTree;
  2265. end;
  2266. procedure TDMDataBase.AssignQtyItemUnitPrice(const aCode: string;
  2267. aUnitPrice: Double);
  2268. var
  2269. cdsFilter: TClientDataSet;
  2270. begin
  2271. cdsFilter := TClientDataSet.Create(nil);
  2272. with cdsFilter do
  2273. begin
  2274. { keep filter when clonecursor }
  2275. CloneCursor(cdsBills, False, True);
  2276. Filter := Format('B_Code=''%s''', [aCode]);
  2277. Filtered := True;
  2278. while not Eof do
  2279. begin
  2280. Edit;
  2281. FieldByName('UnitPrice').AsFloat := aUnitPrice;
  2282. Post;
  2283. Next;
  2284. end;
  2285. Free;
  2286. end;
  2287. end;
  2288. procedure TDMDataBase.BeginImport;
  2289. begin
  2290. FEnabledUITreeEvt(False);
  2291. cdsBills.Filter := 'B_Code<>''''';
  2292. cdsBills.Filtered := True;
  2293. end;
  2294. procedure TDMDataBase.EndImport;
  2295. begin
  2296. cdsBills.Filtered := False;
  2297. FEnabledUITreeEvt(True);
  2298. end;
  2299. procedure TDMDataBase.SetIsProjectBills(const Value: Boolean);
  2300. begin
  2301. FIsProjectBills := Value;
  2302. if FIsProjectBills then
  2303. TDMDetailItems(FDetailItemsDM).RefreshPPItems
  2304. else
  2305. TDMDetailItems(FDetailItemsDM).PPEmptyDetail;
  2306. end;
  2307. procedure TDMDataBase.SetStdBillsCtrl(Value: TObject);
  2308. begin
  2309. FStdBillsCtrl := Value;
  2310. if Assigned(FStdBillsCtrl) then
  2311. begin
  2312. FDetailItemsDM := TProject(FProject).DetailItemsDM;
  2313. FStdLib := TStdBillsCtrl(FStdBillsCtrl).DMStdBillsLib;
  2314. FStdTree := TDMStdBillsLib(FStdLib).StdBillsTree;
  2315. FStdBQTree := TDMStdBillsLib(FStdLib).BillsQtyTree;
  2316. end
  2317. else
  2318. begin
  2319. FDetailItemsDM := nil;
  2320. FStdLib := nil;
  2321. FStdTree := nil;
  2322. FStdBQTree := nil;
  2323. end;
  2324. end;
  2325. procedure TDMDataBase.CheckTree(aNode: TZjIDTreeNode);
  2326. var
  2327. ztnParentNode: TZjIDTreeNode;
  2328. ztnNextNode: TZjIDTreeNode;
  2329. begin
  2330. if aNode = nil then Exit;
  2331. ztnParentNode := aNode.Parent;
  2332. ztnNextNode := aNode.NextSibling;
  2333. if ztnParentNode = nil then
  2334. begin
  2335. if aNode.ParentID <> -1 then
  2336. raise Exception.Create(Format('%d %d %d', [aNode.ID, aNode.ParentID, aNode.NextSiblingID]));
  2337. end
  2338. else
  2339. begin
  2340. if aNode.ParentID <> ztnParentNode.ID then
  2341. raise Exception.Create(Format('%d %d %d', [aNode.ID, aNode.ParentID, aNode.NextSiblingID]));
  2342. end;
  2343. if ztnNextNode = nil then
  2344. begin
  2345. if aNode.NextSiblingID <> -1 then
  2346. raise Exception.Create(Format('%d %d %d', [aNode.ID, aNode.ParentID, aNode.NextSiblingID]));
  2347. end
  2348. else
  2349. begin
  2350. if aNode.NextSiblingID <> ztnNextNode.ID then
  2351. raise Exception.Create(Format('%d %d %d', [aNode.ID, aNode.ParentID, aNode.NextSiblingID]));
  2352. end;
  2353. CheckTree(aNode.FirstChild);
  2354. CheckTree(aNode.NextSibling);
  2355. end;
  2356. procedure TDMDataBase.EnterXMJBills;
  2357. begin
  2358. cdsXMJBills.CloneCursor(cdsBills, True);
  2359. cdsXMJBills.IndexFieldNames := SID;
  2360. cdsXMJBills.Filter := '(Code<>'''') or (ID<100)';
  2361. cdsXMJBills.Filtered := True;
  2362. FXMJBillsTree.DataSet := cdsXMJBills;
  2363. FXMJBillsTree.Active := True;
  2364. end;
  2365. procedure TDMDataBase.LeaveXMJBills;
  2366. begin
  2367. cdsXMJBills.Active := False;
  2368. FXMJBillsTree.DataSet := nil;
  2369. FXMJBillsTree.Active := False;
  2370. end;
  2371. procedure TDMDataBase.cdsXMJBillsAfterScroll(DataSet: TDataSet);
  2372. begin
  2373. if FIsProjectBills then
  2374. begin
  2375. Screen.Cursor := crHourGlass;
  2376. try
  2377. TDMDetailItems(FDetailItemsDM).RefreshPPItems;
  2378. finally
  2379. Screen.Cursor := crDefault;
  2380. end;
  2381. end;
  2382. end;
  2383. procedure TDMDataBase.cdsOrgBillsUnitPriceGetText(Sender: TField;
  2384. var Text: String; DisplayText: Boolean);
  2385. begin
  2386. // Modified by GiLi 2012-3-19 18:48:19
  2387. // 双击编辑Cell的时候,DisplayText=False,所以值为0了
  2388. //if DisplayText then
  2389. begin
  2390. TFieldAccess(Sender).GetText(Text, DisplayText);
  2391. if Text = '0' then Text := '';
  2392. end;
  2393. end;
  2394. constructor TDMDataBase.Create(aProject: TObject);
  2395. begin
  2396. inherited Create(nil);
  2397. FCurIsGatherQ := False;
  2398. FProject := aProject;
  2399. end;
  2400. procedure TDMDataBase.SelectGatherNode(aNode: TZjIDTreeNode;
  2401. aSelected: Boolean);
  2402. var
  2403. ztnNode: TZjIDTreeNode;
  2404. begin
  2405. if aNode = nil then Exit;
  2406. if aSelected then // Select
  2407. begin
  2408. if ((Pos('K', TScBillsItem(aNode).SBillName) <> 0)
  2409. and
  2410. (Pos('+', TScBillsItem(aNode).SBillName) <> 0)
  2411. or
  2412. (Pos('第', TScBillsItem(aNode).SBillName) <> 0)
  2413. and
  2414. (Pos('级', TScBillsItem(aNode).SBillName) <> 0)
  2415. or
  2416. (Pos('k', TScBillsItem(aNode).SBillName) <> 0)
  2417. and
  2418. (Pos('+', TScBillsItem(aNode).SBillName) <> 0)
  2419. or
  2420. (Pos('K', TScBillsItem(aNode).SBillName) <> 0)
  2421. and
  2422. (Pos('+', TScBillsItem(aNode).SBillName) <> 0)
  2423. or
  2424. (Pos('k', TScBillsItem(aNode).SBillName) <> 0)
  2425. and
  2426. (Pos('+', TScBillsItem(aNode).SBillName) <> 0))
  2427. and
  2428. (not IsContainXXItem(TScBillsItem(aNode).SBillCode))
  2429. then
  2430. begin
  2431. if not TScBillsItem(aNode).Selected then
  2432. begin
  2433. TScBillsItem(aNode).Selected := True;
  2434. ztnNode := FBillsTree.FindNode(aNode.ID);
  2435. if Assigned(ztnNode) then
  2436. TScBillsItem(ztnNode).SyncSelected(True);
  2437. end;
  2438. end
  2439. else
  2440. begin
  2441. {if TScBillsItem(aNode).Selected then
  2442. begin
  2443. TScBillsItem(aNode).Selected := False;
  2444. ztnNode := FBillsTree.FindNode(aNode.ID);
  2445. if Assigned(ztnNode) then
  2446. TScBillsItem(ztnNode).SyncSelected(False);
  2447. end; }
  2448. end;
  2449. end
  2450. else // abolish
  2451. begin
  2452. if TScBillsItem(aNode).Selected then
  2453. begin
  2454. TScBillsItem(aNode).Selected := False;
  2455. ztnNode := FBillsTree.FindNode(aNode.ID);
  2456. if Assigned(ztnNode) then
  2457. TScBillsItem(ztnNode).SyncSelected(False);
  2458. end;
  2459. end;
  2460. SelectGatherNode(aNode.FirstChild, aSelected);
  2461. SelectGatherNode(aNode.NextSibling, aSelected);
  2462. end;
  2463. function TDMDataBase.CalculateAll: Double;
  2464. var
  2465. dFirstSum: Double;
  2466. dSecondSum: Double;
  2467. begin
  2468. { 第一部分 }
  2469. dFirstSum := CalculateNode(FBillsTree.FirstNode);
  2470. { 第二部分 }
  2471. dSecondSum := CalculateNode(FBillsTree.FirstNode.NextSibling);
  2472. { 总额 }
  2473. // Result := CalculateOther(dFirstSum, dSecondSum);
  2474. end;
  2475. function TDMDataBase.CalculateNode(aNode: TZjIDTreeNode): Double;
  2476. var
  2477. I: Integer;
  2478. ztnChild: TZjIDTreeNode;
  2479. begin
  2480. Result := 0;
  2481. if aNode = nil then Exit;
  2482. if not aNode.HasChildren then
  2483. begin
  2484. Result := CalculateSingle(aNode);
  2485. end
  2486. else
  2487. begin
  2488. for I := 0 to aNode.ChildCount - 1 do
  2489. begin
  2490. ztnChild := aNode.ChildNodes[I];
  2491. Result := Result + CalculateNode(ztnChild);
  2492. end;
  2493. CalculateNode(aNode, Result);
  2494. end;
  2495. end;
  2496. function TDMDataBase.CalculateOther(aFirstSum, aSecondSum: Double): Double;
  2497. begin
  2498. { 概预算总金额 }
  2499. if FindBills(cdsBills, GYTotalPriceID) then
  2500. begin
  2501. cdsBills.Edit;
  2502. cdsBillsTotalPrice.Value := aFirstSum + aSecondSum;
  2503. cdsBills.Post;
  2504. end;
  2505. { 公路基本造价 }
  2506. if FindBills(cdsBills, GLBaseCost) then
  2507. begin
  2508. cdsBills.Edit;
  2509. cdsBillsTotalPrice.Value := aFirstSum + aSecondSum;
  2510. cdsBills.Post;
  2511. end;
  2512. end;
  2513. function TDMDataBase.FindBills(aCdsDataset: TClientDataSet; aID: Integer): Boolean;
  2514. begin
  2515. aCdsDataset.EditKey;
  2516. aCdsDataset.FieldByName(SID).AsInteger := aID;
  2517. Result := aCdsDataset.GotoKey;
  2518. end;
  2519. procedure TDMDataBase.CalculateNode(aNode: TZjIDTreeNode;
  2520. aTotalPrice: Double);
  2521. begin
  2522. { 单价2位小数, 数量3位小数 }
  2523. if FindBills(cdsBills, aNode.ID) then
  2524. begin
  2525. cdsBills.Edit;
  2526. cdsBillsTotalPrice.Value := aTotalPrice;
  2527. if aNode.HasChildren then
  2528. begin
  2529. if TScBillsItem(aNode).SBillCode <> '' then
  2530. begin
  2531. if cdsBillsDesignQuantity.AsFloat <> 0 then
  2532. cdsBillsDesignPrice.Value := ScRoundTo(aTotalPrice/cdsBillsDesignQuantity.Value, -2)
  2533. else
  2534. cdsBillsDesignPrice.Value := 0;
  2535. end
  2536. else
  2537. begin
  2538. if cdsBillsQuantity.AsFloat <> 0 then
  2539. cdsBillsUnitPrice.Value := ScRoundTo(aTotalPrice/cdsBillsQuantity.Value, -2)
  2540. else
  2541. cdsBillsUnitPrice.Value := 0;
  2542. end;
  2543. end;
  2544. cdsBills.Post;
  2545. end;
  2546. end;
  2547. function TDMDataBase.CalculateSingle(aNode: TZjIDTreeNode): Double;
  2548. begin
  2549. if FindBills(cdsBills, aNode.ID) then
  2550. begin
  2551. if TScBillsItem(aNode).SBillCode <> '' then
  2552. Result := ScRoundTo(cdsBillsDesignQuantity.Value * cdsBillsDesignPrice.Value, 0)
  2553. else
  2554. Result := ScRoundTo(cdsBillsQuantity.Value * cdsBillsUnitPrice.Value, 0);
  2555. if cdsBillsTotalPrice.Value <> Result then
  2556. begin
  2557. cdsBills.Edit;
  2558. cdsBillsTotalPrice.Value := Result;
  2559. cdsBills.Post;
  2560. end;
  2561. end;
  2562. end;
  2563. procedure TDMDataBase.cdsXMJBillsQuantityGetText(Sender: TField;
  2564. var Text: String; DisplayText: Boolean);
  2565. begin
  2566. if DisplayText then
  2567. begin
  2568. TFieldAccess(Sender).GetText(Text, DisplayText);
  2569. if Text = '0' then Text := '';
  2570. end
  2571. end;
  2572. procedure TDMDataBase.AscendSumToParent(aParent: TZjIDTreeNode; aOldSum,
  2573. aNewSum: Double);
  2574. begin
  2575. if aParent = nil then Exit;
  2576. if FindBills(cdsBills, aParent.ID) then
  2577. begin
  2578. cdsBills.Edit;
  2579. cdsBillsTotalPrice.Value := cdsBillsTotalPrice.AsFloat + aNewSum - aOldSum;
  2580. if aParent.HasChildren then
  2581. begin
  2582. if cdsBillsCode.AsString <> '' then
  2583. begin
  2584. if cdsBillsDesignQuantity.AsFloat <> 0 then
  2585. cdsBillsDesignPrice.Value := ScRoundTo(cdsBillsTotalPrice.AsFloat/cdsBillsDesignQuantity.AsFloat, -2)
  2586. else
  2587. cdsBillsDesignPrice.Value := 0;
  2588. end
  2589. else
  2590. begin
  2591. if cdsBillsQuantity.AsFloat <> 0 then
  2592. cdsBillsUnitPrice.Value := ScRoundTo(cdsBillsTotalPrice.AsFloat/cdsBillsQuantity.AsFloat, -2)
  2593. else
  2594. cdsBillsUnitPrice.Value := 0;
  2595. end;
  2596. end;
  2597. cdsBills.Post;
  2598. end;
  2599. AscendSumToParent(aParent.Parent, aOldSum, aNewSum);
  2600. end;
  2601. function TDMDataBase.InsertItem(aNode: TZjIDTreeNode; const aCode, aName: string;
  2602. aIsCode: Boolean): TZjIDTreeNode;
  2603. var
  2604. ztnParent: TZjIDTreeNode;
  2605. begin
  2606. Result := nil;
  2607. if aIsCode then
  2608. begin
  2609. if Pos(TScBillsItem(aNode).SBillCode + '-', aCode) = 1 then
  2610. begin
  2611. Result := FBillsTree.AddBillsItem(aNode.ID, -1);
  2612. TScBillsItem(Result).SBillCode := aCode;
  2613. TScBillsItem(Result).SBillName := aName;
  2614. end
  2615. else
  2616. begin
  2617. Result := FBillsTree.AddBillsItem(aNode.ParentID, aNode.NextSiblingID);
  2618. TScBillsItem(Result).SBillCode := aCode;
  2619. TScBillsItem(Result).SBillName := aName;
  2620. { ztnParent := aNode.Parent;
  2621. while Assigned(ztnParent) do
  2622. begin
  2623. if Pos(TScBillsItem(ztnParent).SBillCode + '-', aCode) = 1 then
  2624. begin
  2625. Result := FBillsTree.AddBillsItem(ztnParent.ID, aNode.NextSiblingID);
  2626. Break;
  2627. end;
  2628. aNode := ztnParent;
  2629. ztnParent := ztnParent.Parent;
  2630. end; }
  2631. end;
  2632. end
  2633. else
  2634. begin
  2635. if TScBillsItem(aNode).SBillCode <> '' then
  2636. begin
  2637. Result := FBillsTree.AddBillsItem(aNode.ID, -1);
  2638. TScBillsItem(Result).SBillBCode := aCode;
  2639. TScBillsItem(Result).SBillName := aName;
  2640. Exit;
  2641. end;
  2642. if Pos(TScBillsItem(aNode).SBillBCode + '-', aCode) = 1 then
  2643. begin
  2644. Result := FBillsTree.AddBillsItem(aNode.ID, -1);
  2645. TScBillsItem(Result).SBillBCode := aCode;
  2646. TScBillsItem(Result).SBillName := aName;
  2647. end
  2648. else
  2649. begin
  2650. Result := FBillsTree.AddBillsItem(aNode.ParentID, aNode.NextSiblingID);
  2651. TScBillsItem(Result).SBillBCode := aCode;
  2652. TScBillsItem(Result).SBillName := aName;
  2653. { ztnParent := aNode.Parent;
  2654. while Assigned(ztnParent) do
  2655. begin
  2656. if Pos(TScBillsItem(ztnParent).SBillBCode + '-', aCode) = 1 then
  2657. begin
  2658. Result := FBillsTree.AddBillsItem(ztnParent.ID, aNode.NextSiblingID);
  2659. Break;
  2660. end;
  2661. if TScBillsItem(ztnParent).SBillCode <> '' then
  2662. begin
  2663. Result := FBillsTree.AddBillsItem(ztnParent.ID, aNode.NextSiblingID);
  2664. Break;
  2665. end;
  2666. aNode := ztnParent;
  2667. ztnParent := ztnParent.Parent;
  2668. end; }
  2669. end;
  2670. end;
  2671. end;
  2672. procedure TDMDataBase.SaveSerialNo;
  2673. var
  2674. I: Integer;
  2675. vNode: TZjIDTreeNode;
  2676. begin
  2677. // TimeBegin('TDMDataBase.SaveSerialNo');
  2678. CloneActive(False);
  2679. FEnabledUITreeEvt(False);
  2680. for I := 0 to FBillsTree.Count - 1 do
  2681. begin
  2682. vNode := FBillsTree.Items[I];
  2683. if cdsBills.FindKey([vNode.ID]) then
  2684. begin
  2685. cdsBills.Edit;
  2686. cdsBillsSerialNo.Value := vNode.MajorIndex;
  2687. cdsBills.Post;
  2688. end;
  2689. end;
  2690. FEnabledUITreeEvt(True);
  2691. CloneActive(true);
  2692. // TimeEnd();
  2693. end;
  2694. function TDMDataBase.CanUnDoBillsText: Boolean;
  2695. begin
  2696. Result := FBillsUndoRef > 0;
  2697. end;
  2698. function TDMDataBase.CanUnDoDrawQtyText: Boolean;
  2699. begin
  2700. Result := FDrawQtyUndoRef > 0;
  2701. end;
  2702. procedure TDMDataBase.UnDoBillsText;
  2703. begin
  2704. Dec(FBillsUndoRef);
  2705. if FBillsUndoRef < 0 then FBillsUndoRef := 0;
  2706. cdsOrgBills.UndoLastChange(True);
  2707. end;
  2708. procedure TDMDataBase.UnDoDrawQtyText;
  2709. begin
  2710. Dec(FDrawQtyUndoRef);
  2711. if FDrawQtyUndoRef < 0 then FDrawQtyUndoRef := 0;
  2712. cdsOrgDrawingQuantity.UndoLastChange(True);
  2713. end;
  2714. procedure TDMDataBase.cdsOrgDrawingQuantityBeforeEdit(DataSet: TDataSet);
  2715. begin
  2716. Inc(FDrawQtyUndoRef);
  2717. end;
  2718. procedure TDMDataBase.cdsBillsAfterInsert(DataSet: TDataSet);
  2719. begin
  2720. FBillsUndoRef := 0;
  2721. cdsBillsIsCreatePriceAnalysis.Value := True;
  2722. end;
  2723. procedure TDMDataBase.cdsDrawingQuantityAfterInsert(DataSet: TDataSet);
  2724. begin
  2725. FDrawQtyUndoRef := 0;
  2726. end;
  2727. procedure TDMDataBase.LocateProjectBills;
  2728. begin
  2729. cdsOrgBills.GotoCurrent(cdsXMJBills);
  2730. end;
  2731. procedure TDMDataBase.LocateBills(const aCode: string);
  2732. begin
  2733. cdsOrgBills.Locate(sCode, aCode, []);
  2734. end;
  2735. (* 以下注释需保留
  2736. 该方法被注释,下面对它进行重写,主要是对速度进行优化。另外该方法中有漏行的自动处理,
  2737. 下面的方法没有,注意备份。
  2738. procedure TDMDataBase.Grade(AllScope: Boolean);
  2739. var
  2740. i, iID, iChildCount, iPreCount, iNextCount, idxFirst, idxLast: Integer;
  2741. vBItem, vLostBItem, vPreBItem, vNextBItem: TScBillsItem;
  2742. vStdItem, vLostStdPaItem, vPreStdItem, vNextStdItem: TStdBillNode;
  2743. sHint, sTemplateCode: string;
  2744. IsLostChildren: Boolean;
  2745. vBC: TBillCategory;
  2746. // 扣分及错误信息
  2747. procedure MarkAndHint(AItem: TScBillsItem; ABC: TBillCategory; AEC: TErrorCategory; ACount: Integer = 1);
  2748. var cSDMark, cMark: Currency;
  2749. sEHint: string;
  2750. begin
  2751. cSDMark := StdDeductMark(ABC, AEC, ACount);
  2752. if cSDMark <> 0 then
  2753. begin
  2754. cMark := AItem.DeductGrade;
  2755. cMark := cMark + cSDMark;
  2756. if Abs(cMark) > AItem.StandardGrade then
  2757. cMark := - AItem.StandardGrade;
  2758. AItem.DeductGrade := cMark;
  2759. end;
  2760. case AEC of
  2761. ecLostChildren, ecLostPreSibling, ecLostNextSibling:
  2762. begin
  2763. sEHint := Format(ErrorHintAry[Ord(AEC)], [ACount]);
  2764. end
  2765. else
  2766. sEHint := ErrorHintAry[Ord(AEC)];
  2767. end;
  2768. if AItem.ErrorHint = '' then
  2769. AItem.ErrorHint := sEHint
  2770. else
  2771. AItem.ErrorHint := AItem.ErrorHint + HintSeparator + sEHint;
  2772. end;
  2773. {标准项目表清单名称含:①××②…×…③ K字打头:K×和K…
  2774. 的忽略。这里不判断用户输入的清单名称,只判断标准项目表清单的名称。}
  2775. function IsSpecialName(AName: string): Boolean;
  2776. begin
  2777. if (UpCase(AName[1]) = 'K') or (Pos('××', AName) > 0) or
  2778. (Pos('…×…', AName) > 0) then
  2779. Result := True
  2780. else
  2781. Result := False;
  2782. end;
  2783. {如下情况不属于深度超出:1-4-5-1下有复杂的子项;1-4-5-2下也有,但在标准项目表中
  2784. 没有罗列出来。当在项目表中出现时不能说它是深度超出。所以:含×××的清单Ax,
  2785. 第一兄弟A1,父项A,从A继承下来的其它清单,要依据A1检查名称、单位等是否错误。
  2786. 1-4-5 大桥工程
  2787. 1-4-5-1 ×××大桥
  2788. 1-4-5-1-1
  2789. 1-4-5-1-2
  2790. ……
  2791. ……
  2792. 1-4-5-2 ×××大桥
  2793. 1-4-5-n ×××大桥
  2794. 当能够调用该方法时,已经确定当前项在标准项目表中找不到了。所以它一定不是第一子
  2795. 结点(为其它兄弟结点提供模板)。ATemplateCode值为模板Code,如:1-4-5-2-1-3的
  2796. ATemplateCode值为1-4-5-1-1-3,将父编号后的两个'-'之间的数字替换成1}
  2797. function IsXXItem(ACode: string; var ATemplateCode: string): Boolean;
  2798. var i, iPos: Integer;
  2799. sXXPCode, sTemp, sTail: string;
  2800. begin
  2801. Result := False;
  2802. ATemplateCode := '';
  2803. for i := Low(aryXXParentCode) to High(aryXXParentCode) do
  2804. begin
  2805. sXXPCode := aryXXParentCode[i];
  2806. if Pos(sXXPCode + '-', ACode) = 1 then
  2807. begin
  2808. Result := True;
  2809. sTemp := ACode;
  2810. Delete(sTemp, 1, Length(sXXPCode) + 1);
  2811. iPos := Pos('-', sTemp);
  2812. if iPos > 0 then
  2813. sTail := Copy(sTemp, iPos, Length(sTemp) - iPos + 1)
  2814. else
  2815. sTail := '';
  2816. ATemplateCode := sXXPCode + '-1' + sTail;
  2817. Break;
  2818. end;
  2819. end;
  2820. end;
  2821. begin
  2822. if not TScBillsItem(FBillsTree[1]).HasChildren then Exit;
  2823. with TStdBillsCtrl(TProject(FProject).StdBillsCtrl).DMStdBillsLib do
  2824. begin
  2825. if not Assigned(FStdTree.Items[0]) then
  2826. begin
  2827. CreateProgressForm(100, '打开标准项目表>>>');
  2828. AddProgressForm(25, '正在为第一次使用创建“分项清单”树...');
  2829. LoadNewStdLib(ExtractFilePath(Application.ExeName) + 'StdLibs\广东分项清单2010版.dat');
  2830. end;
  2831. if not Assigned(FStdBQTree.Items[0]) then
  2832. begin
  2833. AddProgressForm(35, '正在为第一次使用创建“工程量清单”树...');
  2834. LoadBillsQtyLib(ExtractFilePath(Application.ExeName) + 'StdLibs\广东工程量清单2010版.dat' );
  2835. end;
  2836. end;
  2837. // 全部评分
  2838. if AllScope then
  2839. begin
  2840. idxFirst := FBillsTree[1].MajorIndex + 1;
  2841. idxLast := FBillsTree[1].LastPosterity.MajorIndex;
  2842. end
  2843. else // 只评选中项
  2844. begin
  2845. idxFirst := FBillsTree.Selected.MajorIndex + 1;
  2846. idxLast := FBillsTree.Selected.LastPosterity.MajorIndex;
  2847. end;
  2848. // “10”是为后面的统计Stat预留的进度
  2849. CreateProgressForm(idxLast + 10, '正在评分,请稍候>>>');
  2850. for i := idxFirst to idxLast do
  2851. begin
  2852. vBItem := FBillsTree.Items[i];
  2853. AddProgressForm(1, vBItem.Code + vBItem.B_Code + ' ' + vBItem.Name);
  2854. // 保留用户修改
  2855. if vBItem.UserModified = True then
  2856. Continue
  2857. // 先清掉原始评分信息
  2858. else
  2859. begin
  2860. vBItem.ErrorHint := '';
  2861. vBItem.DeductGrade := 0;
  2862. vBItem.IsSuperscale := False;
  2863. vBItem.LostPreSiblingCount := 0;
  2864. vBItem.LostChildrenCount := 0;
  2865. vBItem.LostNextSiblingCount := 0;
  2866. vBItem.StandardGrade := StdMark(vBItem.Code, vBItem.B_Code);
  2867. end;
  2868. // 指定忽略
  2869. if vBItem.IsIgNore = True then
  2870. begin
  2871. vBItem.UserModified := False;
  2872. Continue;
  2873. end;
  2874. // 重复行
  2875. if TScBillsItem(vBItem.Parent).IsRepeat or (
  2876. Assigned(vBItem.PrevSibling) and
  2877. ((TScBillsItem(vBItem.PrevSibling).Code = vBItem.Code) and
  2878. (TScBillsItem(vBItem.PrevSibling).B_Code = vBItem.B_Code) and
  2879. (TScBillsItem(vBItem.PrevSibling).Name = vBItem.Name))) then
  2880. begin
  2881. vBItem.IsRepeat := True;
  2882. MarkAndHint(vBItem, bcAll, ecRepeatLine);
  2883. end
  2884. else
  2885. vBItem.IsRepeat := False;
  2886. // 深度超出
  2887. // 情况1:父结点深度超出,子结点跟随深度超出
  2888. if TScBillsItem(vBItem.Parent).IsSuperscale then
  2889. begin
  2890. vBItem.IsSuperscale := True;
  2891. MarkAndHint(vBItem, bcAll, ecSuperscale);
  2892. end
  2893. else
  2894. vBItem.IsSuperscale := False;
  2895. // 标准项目表部分---------------------------------------------------------------
  2896. if vBItem.NeedSearchInStdLib then
  2897. begin
  2898. vLostBItem := nil;
  2899. vLostStdPaItem := nil;
  2900. { 兵分两路:预算项目节直接在分项清单树中查找。清单子目号清单可以任意放位置,
  2901. 放在另外一个位置不能说它错。所以只能在工程量清单树中遍历。
  2902. 并检查名称、单位是否正确。如果整个表都查不到证明编号错误。}
  2903. vBC := BillCategory(vBItem.Code, vBItem.B_Code);
  2904. case vBC of
  2905. bcYSXMJ:
  2906. vStdItem := FStdTree.FindNode(vBItem, vLostBItem, vLostStdPaItem);
  2907. bcQDZMH:
  2908. begin
  2909. vStdItem := FStdBQTree.FindNode(vBItem.Code, vBItem.B_Code);
  2910. end;
  2911. end;
  2912. //---标准项目表找不到-----------------------------------------------------
  2913. if not Assigned(vStdItem) then
  2914. begin
  2915. case vBC of
  2916. bcYSXMJ:
  2917. begin
  2918. // 深度超出情况2:标准项目表已无子结点
  2919. if (not vLostStdPaItem.HasChildren) or
  2920. // 深度超出情况3:标准项目表有子结点,但是是清单级清单,而当前要比较的是预算级清单
  2921. ((vBItem.Category = bcYSXMJ) and (not vLostStdPaItem.HasYsxmjChild)) then
  2922. begin
  2923. if IsXXItem(vBItem.Code, sTemplateCode) then
  2924. begin
  2925. // 根据模板检查名称、单位(这里不用遍历树,使用cdsYSFastSearch,建有索引,优化速度)
  2926. with TStdBillsCtrl(FStdBillsCtrl).DMStdBillsLib do
  2927. begin
  2928. if cdsYSFastSearch.Locate('Code', vBItem.Code, []) then
  2929. begin
  2930. // 检查名称
  2931. if vBItem.Name <> cdsYSFastSearchName.AsString then
  2932. begin
  2933. if (not IsSpecialName(cdsYSFastSearchName.AsString)) and
  2934. (not LooseCompareIsSame(vBItem.Name, cdsYSFastSearchName.AsString)) then
  2935. begin
  2936. MarkAndHint(vBItem, vBC, ecNameError);
  2937. vBItem.NameErrorFlag := 1;
  2938. end;
  2939. end;
  2940. // 检查单位
  2941. if not SameText(ConvertUnitStr(vBItem.Units),
  2942. ConvertUnitStr(cdsYSFastSearchUnit.AsString)) then
  2943. begin
  2944. MarkAndHint(vBItem, vBC, ecUnitError);
  2945. vBItem.UnitsErrorFlag := 1;
  2946. end;
  2947. end;
  2948. end;
  2949. end
  2950. else // 排除了XX项,这时才能认定是真正的深度超出
  2951. begin
  2952. vBItem.IsSuperscale := True;
  2953. MarkAndHint(vBItem, bcAll, ecSuperscale);
  2954. vBItem.IsSuperscale := True;
  2955. end;
  2956. end
  2957. // 编号错误
  2958. else
  2959. MarkAndHint(vBItem, bcYSXMJ, ecCodeError);
  2960. end;
  2961. bcQDZMH:
  2962. begin
  2963. MarkAndHint(vBItem, bcQDZMH, ecB_CodeError);
  2964. end;
  2965. end;
  2966. end
  2967. // ---标准项目表找到了----------------------------------------------------
  2968. else
  2969. begin
  2970. // 检查名称
  2971. if vBItem.Name <> vStdItem.Name then
  2972. begin
  2973. if (not IsSpecialName(vStdItem.Name)) and (not LooseCompareIsSame(vBItem.Name, vStdItem.Name)) then
  2974. begin
  2975. MarkAndHint(vBItem, vBItem.Category, ecNameError);
  2976. vBItem.NameErrorFlag := 1;
  2977. end;
  2978. end;
  2979. // 检查单位
  2980. if not SameText(ConvertUnitStr(vBItem.Units), ConvertUnitStr(vStdItem.Units)) then
  2981. begin
  2982. MarkAndHint(vBItem, vBItem.Category, ecUnitError);
  2983. vBItem.UnitsErrorFlag := 1;
  2984. end;
  2985. {
  2986. // 漏行-------------------------------------------------------------------
  2987. // 情况①:深度不够,即漏孩子
  2988. // IsLostChildren := False;
  2989. if (not vBGNode.HasChildren) and vStdItem.HasChildren then
  2990. begin
  2991. // IsLostChildren := True;
  2992. iChildCount := GetAllChildrenCount(vStdItem);
  2993. cdsBillsLostChildrenCount.AsInteger := iChildCount;
  2994. cdsBillsStandardGrade.AsCurrency := cdsBillsStandardGrade.AsCurrency
  2995. + (-StdDeductMark(bcAll, ecLostChildren, iChildCount));
  2996. MarkAndHint(bcAll, ecLostChildren, iChildCount);
  2997. end;
  2998. // 情况②:漏前兄弟:二个号一个名称三者完全一致才视为前兄弟存在
  2999. vPreBGNode := TBGNode(vBGNode.PrevSibling);
  3000. vPreStdItem := TStdItem(vStdItem.PrevSibling);
  3001. if Assigned(vPreBGNode) and Assigned(vPreStdItem) then
  3002. begin
  3003. if not ((vPreBGNode.B_Code = vPreStdItem.B_Code) and
  3004. (vPreBGNode.Code = vPreStdItem.Code) and
  3005. (vPreBGNode.Name = vPreStdItem.Name)) then
  3006. begin
  3007. // 这里要包括前兄弟自身也漏了
  3008. iPreCount := GetAllChildrenCount(vPreStdItem) + 1;
  3009. cdsBillsLostPreSiblingCount.AsInteger := iPreCount;
  3010. cdsBillsStandardGrade.AsCurrency := cdsBillsStandardGrade.AsCurrency
  3011. + (-StdDeductMark(bcAll, ecLostPreSibling, iPreCount));
  3012. MarkAndHint(bcAll, ecLostPreSibling, iPreCount);
  3013. end;
  3014. end;
  3015. // 情况③:漏后兄弟:二个号一个名称三者完全一致才视为后兄弟存在
  3016. // 因为前面已经判断了前兄弟,所以只有最后一个结点需要判断后兄弟
  3017. vNextBGNode := TBGNode(vBGNode.NextSibling);
  3018. if not Assigned(vNextBGNode) then
  3019. begin
  3020. vNextStdItem:= TStdItem(vStdItem.NextSibling);
  3021. if Assigned(vNextStdItem) then
  3022. begin
  3023. // 这里要包括后兄弟自身也漏了
  3024. iNextCount := GetAllChildrenCount(vNextStdItem) + 1;
  3025. cdsBillsLostNextSiblingCount.AsInteger := iNextCount;
  3026. cdsBillsStandardGrade.AsCurrency := cdsBillsStandardGrade.AsCurrency
  3027. + (-StdDeductMark(bcAll, ecLostNextSibling, iNextCount));
  3028. MarkAndHint(bcAll, ecLostNextSibling, iNextCount);
  3029. end;
  3030. end; }
  3031. // 漏行完-----------------------------------------------------------------
  3032. end;
  3033. end;
  3034. // 标准项目表部分结束-----------------------------------------------------------
  3035. // 最后检查3个数量--------------------------------------------------------------
  3036. Case vBC of
  3037. bcYSXMJ: // 预算项目节清单
  3038. begin
  3039. if vBItem.DesignQuantity = 0 then
  3040. begin
  3041. // 缺设计数量1、设计数量2 (两个数量都没填扣2分)
  3042. if vBItem.DesignQuantity2 = 0 then
  3043. MarkAndHint(vBItem, bcYSXMJ, ecNoDesignQuantity)
  3044. // 设计数量2有值 (数量位置错扣0.5分)
  3045. else
  3046. MarkAndHint(vBItem, bcYSXMJ, ecDesignQuantityPosError);
  3047. end;
  3048. end;
  3049. bcQDZMH: // 清单子目号清单: 清单数量错误扣1分
  3050. begin
  3051. if not vBItem.HasChildren then
  3052. if vBItem.Quantity = 0 then
  3053. MarkAndHint(vBItem, bcQDZMH, ecNoQuantity);
  3054. end;
  3055. end;
  3056. SyncGradeFromTreeNodeToDataSet(vBItem);
  3057. end;
  3058. end; *)
  3059. { 以上注释需保留 }
  3060. {-------------------------------------------------------------------------------}
  3061. procedure TDMDataBase.Grade(AllScope: Boolean);
  3062. var
  3063. i, iID, idxFirst, idxLast: Integer;
  3064. vBItem, vLostBItem, vBPaItem: TScBillsItem;
  3065. vStdItem, vLostStdPaItem, vStdPaItem: TStdBillNode;
  3066. sHint, sTemplateCode, vUnits: string;
  3067. IsLostChildren: Boolean;
  3068. vBC: TBillCategory;
  3069. sRightUnit: string;
  3070. // 扣分及错误信息
  3071. procedure MarkAndHint(AItem: TScBillsItem; ABC: TBillCategory; AEC: TErrorCategory; ACount: Integer = 1);
  3072. var cSDMark, cMark: Currency;
  3073. sEHint: string;
  3074. begin
  3075. cSDMark := StdDeductMark(ABC, AEC, ACount);
  3076. if cSDMark <> 0 then
  3077. begin
  3078. cMark := AItem.DeductGrade;
  3079. cMark := cMark + cSDMark;
  3080. if Abs(cMark) > AItem.StandardGrade then
  3081. cMark := - AItem.StandardGrade;
  3082. AItem.DeductGrade := cMark;
  3083. end;
  3084. case AEC of
  3085. ecLostChildren, ecLostPreSibling, ecLostNextSibling:
  3086. begin
  3087. sEHint := Format(ErrorHintAry[Ord(AEC)], [ACount]);
  3088. end
  3089. else
  3090. sEHint := ErrorHintAry[Ord(AEC)];
  3091. end;
  3092. if AItem.ErrorHint = '' then
  3093. AItem.ErrorHint := sEHint
  3094. else
  3095. AItem.ErrorHint := AItem.ErrorHint + HintSeparator + sEHint;
  3096. end;
  3097. {标准项目表清单名称含:①××②…×…③ K字打头:K×和K…
  3098. 的忽略。这里不判断用户输入的清单名称,只判断标准项目表清单的名称。}
  3099. function IsSpecialName(AName: string): Boolean;
  3100. begin
  3101. if (UpCase(AName[1]) = 'K') or (Pos('××', AName) > 0) or
  3102. (Pos('…×…', AName) > 0) then
  3103. Result := True
  3104. else
  3105. Result := False;
  3106. end;
  3107. {如下情况不属于深度超出:1-4-5-1下有复杂的子项;1-4-5-2下也有,但在标准项目表中
  3108. 没有罗列出来。当在项目表中出现时不能说它是深度超出。所以:含×××的清单Ax,
  3109. 第一兄弟A1,父项A,从A继承下来的其它清单,要依据A1检查名称、单位等是否错误。
  3110. 1-4-5 大桥工程
  3111. 1-4-5-1 ×××大桥
  3112. 1-4-5-1-1
  3113. 1-4-5-1-2
  3114. ……
  3115. ……
  3116. 1-4-5-2 ×××大桥
  3117. 1-4-5-n ×××大桥
  3118. 当能够调用该方法时,已经确定当前项在标准项目表中找不到了。所以它一定不是第一子
  3119. 结点(为其它兄弟结点提供模板)。ATemplateCode值为模板Code,如:1-4-5-2-1-3的
  3120. ATemplateCode值为1-4-5-1-1-3,将父编号后的两个'-'之间的数字替换成1}
  3121. function IsXXItem(ACode: string; var ATemplateCode: string): Boolean;
  3122. var i, iPos: Integer;
  3123. sXXPCode, sTemp, sTail: string;
  3124. begin
  3125. Result := False;
  3126. ATemplateCode := '';
  3127. for i := 0 to FXXParentCodeSL.Count - 1 do
  3128. begin
  3129. sXXPCode := FXXParentCodeSL[i];
  3130. if Pos(sXXPCode + '-', ACode) = 1 then
  3131. begin
  3132. Result := True;
  3133. sTemp := ACode;
  3134. Delete(sTemp, 1, Length(sXXPCode) + 1);
  3135. iPos := Pos('-', sTemp);
  3136. if iPos > 0 then
  3137. sTail := Copy(sTemp, iPos, Length(sTemp) - iPos + 1)
  3138. else
  3139. sTail := '';
  3140. ATemplateCode := sXXPCode + '-1' + sTail;
  3141. Break;
  3142. end;
  3143. end;
  3144. end;
  3145. procedure CheckName(AStdName: string);
  3146. begin
  3147. if not SameText(vBItem.Name, AStdName) then
  3148. begin
  3149. if (not IsSpecialName(AStdName)) and
  3150. (not LooseCompareIsSame(vBItem.Name, AStdName)) then
  3151. begin
  3152. MarkAndHint(vBItem, vBItem.Category, ecNameError);
  3153. vBItem.NameErrorFlag := 1;
  3154. vBItem.RightName := AStdName;
  3155. end;
  3156. end;
  3157. end;
  3158. procedure CheckUnits(AStdUnits: string);
  3159. begin
  3160. sRightUnit := AStdUnits;
  3161. if not SameText(ConvertUnitStr(vBItem.Units), ConvertUnitStr(AStdUnits)) then
  3162. begin
  3163. MarkAndHint(vBItem, vBItem.Category, ecUnitError);
  3164. vBItem.UnitsErrorFlag := 1;
  3165. vBItem.RightUnits := AStdUnits;
  3166. end;
  3167. end;
  3168. // 是否有两个单位
  3169. function HasTwoUnits(AUnit: string): Boolean;
  3170. begin
  3171. Result := False;
  3172. if Pos('/', AUnit) > 1 then
  3173. Result := True;
  3174. end;
  3175. begin
  3176. with TStdBillsCtrl(TProject(FProject).StdBillsCtrl).DMStdBillsLib do
  3177. begin
  3178. if not Assigned(FStdTree.Items[0]) then
  3179. begin
  3180. CreateProgressForm(100, '打开标准项目表>>>');
  3181. AddProgressForm(25, '正在为第一次使用创建“分项清单”树...');
  3182. LoadNewStdLib(PBStdTreeFile);
  3183. end;
  3184. if not Assigned(FStdBQTree.Items[0]) then
  3185. begin
  3186. AddProgressForm(35, '正在为第一次使用创建“工程量清单”树...');
  3187. LoadBillsQtyLib(BQStdTreeFile);
  3188. end;
  3189. end;
  3190. // 全部评分
  3191. if AllScope then
  3192. begin
  3193. idxFirst := FBillsTree[1].MajorIndex + 1;
  3194. idxLast := FBillsTree[1].LastPosterity.MajorIndex;
  3195. end
  3196. else // 只评选中项
  3197. begin
  3198. idxFirst := FBillsTree.Selected.MajorIndex;
  3199. if Assigned(FBillsTree.Selected.LastPosterity) then
  3200. idxLast := FBillsTree.Selected.LastPosterity.MajorIndex
  3201. else
  3202. idxLast := idxFirst;
  3203. end;
  3204. // “10”是为后面的统计Stat预留的进度
  3205. CreateProgressForm(idxLast + 10, '正在评分,请稍候>>>');
  3206. for i := idxFirst to idxLast do
  3207. begin
  3208. vBItem := FBillsTree.Items[i];
  3209. sRightUnit := vBItem.Units;
  3210. AddProgressForm(1, vBItem.Code + vBItem.B_Code + ' ' + vBItem.Name);
  3211. // 保留用户修改
  3212. if vBItem.UserModified = True then
  3213. Continue
  3214. // 先清掉原始评分信息
  3215. else
  3216. begin
  3217. vBItem.ErrorHint := '';
  3218. vBItem.DeductGrade := 0;
  3219. vBItem.IsSuperscale := False;
  3220. vBItem.LostPreSiblingCount := 0;
  3221. vBItem.LostChildrenCount := 0;
  3222. vBItem.LostNextSiblingCount := 0;
  3223. vBItem.StandardGrade := StdMark(vBItem.Code, vBItem.B_Code);
  3224. end;
  3225. // 指定忽略
  3226. if vBItem.IsIgNore = True then
  3227. begin
  3228. vBItem.UserModified := False;
  3229. Continue;
  3230. end;
  3231. vBC := BillCategory(vBItem.Code, vBItem.B_Code);
  3232. if Assigned(vBItem.Parent) then
  3233. begin
  3234. // 重复行
  3235. if TScBillsItem(vBItem.Parent).IsRepeat or (
  3236. Assigned(vBItem.PrevSibling) and
  3237. ((TScBillsItem(vBItem.PrevSibling).Code = vBItem.Code) and
  3238. (TScBillsItem(vBItem.PrevSibling).B_Code = vBItem.B_Code) and
  3239. (TScBillsItem(vBItem.PrevSibling).Name = vBItem.Name))) then
  3240. begin
  3241. vBItem.IsRepeat := True;
  3242. MarkAndHint(vBItem, bcAll, ecRepeatLine);
  3243. end
  3244. else
  3245. vBItem.IsRepeat := False;
  3246. // 深度超出
  3247. // 情况1:父结点深度超出,子结点跟随深度超出。
  3248. if TScBillsItem(vBItem.Parent).IsSuperscale then
  3249. begin
  3250. vBItem.IsSuperscale := True;
  3251. MarkAndHint(vBItem, bcAll, ecSuperscale);
  3252. end
  3253. else
  3254. vBItem.IsSuperscale := False;
  3255. end
  3256. else
  3257. begin
  3258. vBItem.IsRepeat := False;
  3259. vBItem.IsSuperscale := False;
  3260. end;
  3261. // 标准项目表部分---------------------------------------------------------------
  3262. // if vBItem.NeedSearchInStdLib then
  3263. if not vBItem.IsRepeat then
  3264. begin
  3265. vLostBItem := nil;
  3266. vLostStdPaItem := nil;
  3267. { 兵分两路:预算项目节直接在分项清单树中查找。清单子目号清单可以任意放位置,
  3268. 放在另外一个位置不能说它错。所以只能在工程量清单树中遍历。
  3269. 并检查名称、单位是否正确。如果整个表都查不到证明编号错误。}
  3270. case vBC of
  3271. bcYSXMJ:
  3272. begin
  3273. vStdItem := FStdTree.FindNode(vBItem, vLostBItem, vLostStdPaItem);
  3274. //---标准项目表找不到-----------------------------------------------------
  3275. if not Assigned(vStdItem) then
  3276. begin
  3277. // 如果是XX项,则不能算深度超出,也不能算编号错
  3278. if IsXXItem(vBItem.Code, sTemplateCode) then
  3279. begin
  3280. with TStdBillsCtrl(FStdBillsCtrl).DMStdBillsLib do
  3281. begin
  3282. // 根据模板检查名称、单位(这里不用遍历树,使用cdsYSFastSearch,建有索引,优化速度)
  3283. if cdsFastSearch.Locate('Code', sTemplateCode, []) then
  3284. begin
  3285. // 检查名称
  3286. CheckName(cdsFastSearchName.AsString);
  3287. // 检查单位
  3288. CheckUnits(cdsFastSearchUnit.AsString);
  3289. end
  3290. else // 如果找不到,则属于新增项
  3291. begin
  3292. MarkAndHint(vBItem, bcYSXMJ, ecCodeError);
  3293. if Trim(vBItem.Units) = '' then
  3294. MarkAndHint(vBItem, bcYSXMJ, ecNoUnits);
  3295. end;
  3296. end;
  3297. end
  3298. // 深度超出
  3299. else if
  3300. // 深度超出(情况2:标准项目表已无子结点)
  3301. (not vLostStdPaItem.HasChildren) or
  3302. // 深度超出(情况3:标准项目表有子结点,但只是清单子目,而当前要比较的是预算项目节)
  3303. ((vBItem.Category = bcYSXMJ) and (not vLostStdPaItem.HasYsxmjChild)) then
  3304. begin
  3305. // 如果前面已经判断是深度超出这里就不用重复指定深度超出
  3306. if not vBItem.IsSuperscale then
  3307. begin
  3308. vBItem.IsSuperscale := True;
  3309. MarkAndHint(vBItem, bcAll, ecSuperscale);
  3310. end;
  3311. // 需求1.237 "所有预算项目节行都有单位、设计数量。"
  3312. if Trim(vBItem.Units) = '' then
  3313. MarkAndHint(vBItem, bcYSXMJ, ecNoUnits);
  3314. end
  3315. // 既不是XX项又不是深度超出,那么就是编号错误/新增预算项目节
  3316. else
  3317. begin
  3318. MarkAndHint(vBItem, bcYSXMJ, ecCodeError);
  3319. if Trim(vBItem.Units) = '' then
  3320. MarkAndHint(vBItem, bcYSXMJ, ecNoUnits);
  3321. end;
  3322. end
  3323. // ---标准项目表找到了----------------------------------------------------
  3324. else
  3325. begin
  3326. // 检查名称
  3327. CheckName(vStdItem.Name);
  3328. // 检查单位
  3329. CheckUnits(vStdItem.Units);
  3330. end;
  3331. end;
  3332. bcQDZMH:
  3333. begin
  3334. with TStdBillsCtrl(FStdBillsCtrl).DMStdBillsLib do
  3335. begin
  3336. //---标准项目表找不到-----------------------------------------------------
  3337. if not cdsBQFastSearch.Locate('B_Code', vBItem.B_Code, []) then
  3338. begin
  3339. // 编号递延
  3340. if IsCodeStepItem(vBItem.B_Code, vUnits) then
  3341. begin
  3342. MarkAndHint(vBItem, bcQDZMH, ecCodeStep);
  3343. // 检查单位
  3344. CheckUnits(vUnits);
  3345. end
  3346. else // 编号错误或新清单
  3347. MarkAndHint(vBItem, bcQDZMH, ecB_CodeError);
  3348. // 需求1.236 "所有有子项的清单子目,其数量和单位都应为空白,
  3349. // 所有最底层的清单子目必须有单位和数量。"
  3350. // 该需求不严谨:202-1、202-1-1 前者无单位,后者有单位,如果在
  3351. // 实际项目中只有202-1,则它是最底层清单子目,需求矛盾。所以只
  3352. // 能根据标准项目表判断。所以以下判断只适用于新增清单。
  3353. if (not vBItem.HasChildren) and (Trim(vBItem.Units) = '') then
  3354. MarkAndHint(vBItem, bcQDZMH, ecNoUnits);
  3355. end
  3356. // ---标准项目表找到了----------------------------------------------------
  3357. else
  3358. begin
  3359. // 检查名称
  3360. CheckName(cdsBQFastSearchName.AsString);
  3361. // 检查单位
  3362. CheckUnits(cdsBQFastSearchUnit.AsString);
  3363. end;
  3364. end;
  3365. end;
  3366. end;
  3367. end;
  3368. // 标准项目表部分结束-----------------------------------------------------------
  3369. // 最后检查3个数量--------------------------------------------------------------
  3370. Case vBC of
  3371. bcYSXMJ: // 预算项目节清单
  3372. begin
  3373. // 双单位情况下,两个都必须都有数量。
  3374. if HasTwoUnits(sRightUnit) then
  3375. begin
  3376. if vBItem.DesignQuantity = 0 then
  3377. MarkAndHint(vBItem, bcYSXMJ, ecNoDesignQuantity);
  3378. if vBItem.DesignQuantity2 = 0 then
  3379. MarkAndHint(vBItem, bcYSXMJ, ecNoDesignQuantity2);
  3380. end
  3381. else
  3382. begin
  3383. // 单单位情况下
  3384. // 两个数量都没填扣2分
  3385. if (vBItem.DesignQuantity = 0) and (vBItem.DesignQuantity2 = 0) then
  3386. MarkAndHint(vBItem, bcYSXMJ, ecNoDesignQuantity)
  3387. // 设计数量2有值 (数量位置错扣0.5分)
  3388. else if (vBItem.DesignQuantity = 0) and (vBItem.DesignQuantity2 <> 0) then
  3389. MarkAndHint(vBItem, bcYSXMJ, ecDesignQuantityPosError);
  3390. end;
  3391. end;
  3392. bcQDZMH: // 清单子目号清单: 清单数量错误扣1分
  3393. begin
  3394. if not vBItem.HasChildren then
  3395. if vBItem.Quantity = 0 then
  3396. MarkAndHint(vBItem, bcQDZMH, ecNoQuantity);
  3397. end;
  3398. end;
  3399. SyncGradeFromTreeNodeToDataSet(vBItem);
  3400. end;
  3401. end;
  3402. procedure TDMDataBase.AddError(AEC: TErrorCategory; ACount: Integer);
  3403. var iPos, iValue: Integer;
  3404. sHint, sError: string;
  3405. cMark: Currency;
  3406. vBC: TBillCategory;
  3407. begin
  3408. {$IFNDEF _beEncrypt}
  3409. MessageHint(0, '对不起,此版本不提供评分功能,请购买正式版。');
  3410. Exit;
  3411. {$ENDIF}
  3412. case AEC of
  3413. ecLostPreSibling, ecLostChildren, ecLostNextSibling:
  3414. begin
  3415. if AEC = ecLostPreSibling then
  3416. iValue := cdsOrgBillsLostPreSiblingCount.AsInteger
  3417. else if AEC = ecLostChildren then
  3418. iValue := cdsOrgBillsLostChildrenCount.AsInteger
  3419. else if AEC = ecLostNextSibling then
  3420. iValue := cdsOrgBillsLostNextSiblingCount.AsInteger;
  3421. if iValue = ACount then Exit;
  3422. if ACount <= 0 then Exit;
  3423. // 先处理掉旧的
  3424. CancelError(AEC);
  3425. sError := Format(ErrorHintAry[Ord(AEC)], [ACount]);
  3426. cMark := StdDeductMark(bcAll, AEC, ACount);
  3427. end
  3428. else
  3429. begin
  3430. sHint := cdsOrgBillsErrorHint.AsString;
  3431. sError := ErrorHintAry[Ord(AEC)];
  3432. iPos := Pos(sError, sHint);
  3433. // 错误已存在则不再重复指定
  3434. if iPos > 0 then Exit;
  3435. vBC := BillCategory(cdsOrgBillsCode.AsString, cdsOrgBillsB_Code.AsString);
  3436. cMark := StdDeductMark(vBC, AEC, 1);
  3437. end;
  3438. end;
  3439. cdsOrgBills.Edit;
  3440. sHint := cdsOrgBillsErrorHint.AsString;
  3441. if sHint = '' then
  3442. sHint := sError
  3443. else
  3444. sHint := sHint + HintSeparator + sError;
  3445. cdsOrgBillsErrorHint.AsString := sHint;
  3446. if AEC = ecSuperscale then
  3447. cdsOrgBillsIsSuperscale.AsBoolean := True
  3448. else if AEC in [ecLostChildren, ecLostPreSibling, ecLostNextSibling] then
  3449. cdsOrgBillsStandardGrade.AsCurrency := cdsOrgBillsStandardGrade.AsCurrency
  3450. + (- StdDeductMark(bcAll, AEC, ACount));
  3451. case AEC of
  3452. ecLostChildren: cdsOrgBillsLostChildrenCount.AsInteger := ACount;
  3453. ecLostPreSibling: cdsOrgBillsLostPreSiblingCount.AsInteger := ACount;
  3454. ecLostNextSibling: cdsOrgBillsLostNextSiblingCount.AsInteger := ACount;
  3455. end;
  3456. cdsOrgBillsDeductGrade.AsCurrency := cdsOrgBillsDeductGrade.AsCurrency + cMark;
  3457. if Abs(cdsOrgBillsDeductGrade.AsCurrency) > cdsOrgBillsStandardGrade.AsCurrency then
  3458. cdsOrgBillsDeductGrade.AsCurrency := - cdsOrgBillsStandardGrade.AsCurrency;
  3459. cdsOrgBillsUserModified.AsBoolean := True;
  3460. cdsOrgBills.Post;
  3461. end;
  3462. procedure TDMDataBase.CancelError(AEC: TErrorCategory);
  3463. var
  3464. sHint, sError: string;
  3465. cMark: Currency;
  3466. vBC: TBillCategory;
  3467. // AHint: 字段值(全,包括本清单的所有错误提示);AError:要处理的错误
  3468. procedure DeleteHint(var AHint, AError: string);
  3469. var iPos, LEr, LSpr: Integer;
  3470. begin
  3471. iPos := Pos(AError, AHint);
  3472. if iPos = 0 then Exit;
  3473. LEr := Length(AError);
  3474. LSpr := Length(HintSeparator);
  3475. // 删除提示
  3476. if iPos = 1 then
  3477. begin
  3478. if Length(AHint) > (LEr + LSpr) then
  3479. Delete(AHint, 1, LEr + LSpr)
  3480. else
  3481. Delete(AHint, 1, LEr)
  3482. end
  3483. else
  3484. Delete(AHint, iPos - LSpr, LEr + LSpr);
  3485. end;
  3486. begin
  3487. {$IFNDEF _beEncrypt}
  3488. MessageHint(0, '对不起,此版本不提供评分功能,请购买正式版。');
  3489. Exit;
  3490. {$ENDIF}
  3491. sHint := cdsOrgBillsErrorHint.AsString;
  3492. vBC := BillCategory(cdsOrgBillsCode.AsString, cdsOrgBillsB_Code.AsString);
  3493. case AEC of
  3494. ecLostChildren:
  3495. begin
  3496. if cdsOrgBillsLostChildrenCount.AsInteger <= 0 then Exit;
  3497. sError := Format(ErrorHintAry[Ord(AEC)], [cdsOrgBillsLostChildrenCount.AsInteger]);
  3498. cMark := StdDeductMark(vBC, AEC, cdsOrgBillsLostChildrenCount.AsInteger);
  3499. cdsOrgBills.Edit;
  3500. cdsOrgBillsLostChildrenCount.Clear;
  3501. end;
  3502. ecLostPreSibling:
  3503. begin
  3504. if cdsOrgBillsLostPreSiblingCount.AsInteger <= 0 then Exit;
  3505. sError := Format(ErrorHintAry[Ord(AEC)], [cdsOrgBillsLostPreSiblingCount.AsInteger]);
  3506. cMark := StdDeductMark(vBC, AEC, cdsOrgBillsLostPreSiblingCount.AsInteger);
  3507. cdsOrgBills.Edit;
  3508. cdsOrgBillsLostPreSiblingCount.Clear;
  3509. end;
  3510. ecLostNextSibling:
  3511. begin
  3512. if cdsOrgBillsLostNextSiblingCount.AsInteger <= 0 then Exit;
  3513. sError := Format(ErrorHintAry[Ord(AEC)], [cdsOrgBillsLostNextSiblingCount.AsInteger]);
  3514. cMark := StdDeductMark(vBC, AEC, cdsOrgBillsLostNextSiblingCount.AsInteger);
  3515. cdsOrgBills.Edit;
  3516. cdsOrgBillsLostNextSiblingCount.Clear;
  3517. end
  3518. else
  3519. begin
  3520. sError := ErrorHintAry[Ord(AEC)];
  3521. // 错误不存在无法取消
  3522. if Pos(sError, sHint) = 0 then Exit;
  3523. cMark := StdDeductMark(vBC, AEC, 1);
  3524. cdsOrgBills.Edit;
  3525. end;
  3526. end;
  3527. DeleteHint(sHint, sError);
  3528. cdsOrgBillsErrorHint.AsString := sHint;
  3529. // 扣分加回
  3530. cdsOrgBillsDeductGrade.AsCurrency := cdsOrgBillsDeductGrade.AsCurrency - cMark;
  3531. // 暂时没有加到正分的情况
  3532. if cdsOrgBillsDeductGrade.AsCurrency > 0 then
  3533. cdsOrgBillsDeductGrade.Clear;
  3534. // 标准分加回
  3535. if AEC in [ecLostPreSibling, ecLostChildren, ecLostNextSibling] then
  3536. cdsOrgBillsStandardGrade.AsCurrency := cdsOrgBillsStandardGrade.AsCurrency + cMark;
  3537. // 深度超出要改字段
  3538. if AEC = ecSuperscale then
  3539. cdsOrgBillsIsSuperscale.AsBoolean := False;
  3540. cdsOrgBillsUserModified.AsBoolean := True;
  3541. cdsOrgBills.Post;
  3542. end;
  3543. procedure TDMDataBase.ClearUserFlags;
  3544. begin
  3545. cdsBills.First;
  3546. while not cdsBills.Eof do
  3547. begin
  3548. if cdsBillsUserModified.AsBoolean = True then
  3549. begin
  3550. cdsBills.Edit;
  3551. cdsBillsUserModified.Clear;
  3552. cdsBills.Post;
  3553. end;
  3554. cdsBills.Next;
  3555. end;
  3556. end;
  3557. function TDMDataBase.StdDeductMark(ABillCategory: TBillCategory;
  3558. AErrorCategory: TErrorCategory; ACount: Integer): Currency;
  3559. begin
  3560. Result := 0;
  3561. case AErrorCategory of
  3562. ecRepeatLine: Result := -0.5;
  3563. // 深度超出是在最后算附加分
  3564. ecSuperscale, ecCodeError, ecB_CodeError, ecCodeStep: Result := 0;
  3565. ecLostChildren, ecLostPreSibling, ecLostNextSibling: Result := -1 * ACount
  3566. else
  3567. begin
  3568. case ABillCategory of
  3569. bcYSXMJ:
  3570. begin
  3571. case AErrorCategory of
  3572. ecNameError, ecUnitError, ecDesignQuantityPosError, ecNoUnits: Result := -0.5;
  3573. ecQuantityError, ecNoDesignQuantity, ecNoDesignQuantity2: Result := -1;
  3574. end;
  3575. end;
  3576. bcQDZMH:
  3577. begin
  3578. case AErrorCategory of
  3579. ecNameError, ecUnitError, ecNoUnits: Result := -1;
  3580. ecQuantityError, ecNoQuantity: Result := -2;
  3581. end;
  3582. end;
  3583. end;
  3584. end
  3585. end;
  3586. end;
  3587. function TDMDataBase.StdMark(ACode, AB_Code: string): Currency;
  3588. // 软基、边坡、桥梁、隧道等分部分项工程中预算项目节标准分值为1
  3589. function IsSpecial(ACode: string): Boolean;
  3590. begin
  3591. Result := False;
  3592. ACode := Trim(ACode);
  3593. //1-2-1-4-1 软弱地基处理 软基
  3594. //1-2-1-6 路基防护与加固工程 边坡
  3595. //1-4 桥梁涵洞工程 桥梁
  3596. //1-6 隧道工程 隧道
  3597. //1-5-5-N-1-1-4-1 软弱地基处理 软基
  3598. //1-5-5-N-2-1-4-1 软弱地基处理 软基
  3599. //1-5-5-N-1-1-6 路基防护与加固工程 边坡
  3600. //1-5-5-N-2-1-6 路基防护与加固工程 边坡
  3601. //1-5-5-N-2-1-5-8 高边坡排水 边坡
  3602. if (ACode = '1-2-1-4-1') or (ACode = '1-2-1-6') or
  3603. (ACode = '1-4') or (ACode = '1-6') or
  3604. (Pos('1-2-1-4-1-', ACode) = 1) or (Pos('1-2-1-6-', ACode) = 1) or
  3605. (Pos('1-4-', ACode) = 1) or (Pos('1-6-', ACode) = 1) or
  3606. (
  3607. (Pos('1-5-5-', ACode) = 1) and (
  3608. (Pos('-1-1-4-1', ACode) > 0) or (Pos('-2-1-4-1', ACode) > 0) or
  3609. (Pos('-1-1-6', ACode) > 0) or (Pos('-2-1-6', ACode) > 0) or
  3610. (Pos('-2-1-5-8', ACode) > 0))
  3611. ) then
  3612. Result := True;
  3613. end;
  3614. begin
  3615. Case BillCategory(ACode, AB_Code) of
  3616. bcTZGCL: Result := 1;
  3617. bcYSXMJ:
  3618. begin
  3619. if IsSpecial(ACode) then
  3620. Result := 1.5
  3621. else
  3622. Result := 1;
  3623. end;
  3624. bcQDZMH: result := 2;
  3625. end;
  3626. end;
  3627. function TDMDataBase.StdMark(AItem: TScBillsItem): Currency;
  3628. begin
  3629. StdMark(AItem.Code, AItem.B_Code);
  3630. end;
  3631. function GetAllChildrenCount(ANode: TZjIDTreeNode): Integer;
  3632. function GetCount(ANode: TZjIDTreeNode): Integer;
  3633. begin
  3634. if not Assigned(ANode) then Exit;
  3635. Result := 0;
  3636. Result := Result + ANode.ChildCount;
  3637. if Assigned(ANode.FirstChild) then
  3638. Result := Result + GetCount(ANode.FirstChild);
  3639. if Assigned(ANode.NextSibling) then
  3640. Result := Result + GetCount(ANode.NextSibling);
  3641. end;
  3642. begin
  3643. if not Assigned(ANode) then Exit;
  3644. if Assigned(ANode.FirstChild) then
  3645. Result := GetCount(ANode.FirstChild) + ANode.ChildCount
  3646. else
  3647. Result := 0;
  3648. end;
  3649. function TDMDataBase.Stat: Currency;
  3650. begin
  3651. cdsBills.ApplyUpdates(0);
  3652. cdsStat.DisableControls;
  3653. // 总统计
  3654. aqStatTotal.Close;
  3655. aqStatTotal.Open;
  3656. cdsStatTotal.First;
  3657. while not cdsStatTotal.Eof do
  3658. cdsStatTotal.Delete;
  3659. aqStatTotal.First;
  3660. while not aqStatTotal.Eof do
  3661. begin
  3662. cdsStatTotal.Append;
  3663. cdsStatTotalID.AsInteger := aqStatTotalID.AsInteger;
  3664. cdsStatTotalStandardGradeTotal.AsCurrency := aqStatTotalStandardGradeTotal.AsCurrency;
  3665. cdsStatTotalDeductGradeTotal.AsCurrency := aqStatTotalDeductGradeTotal.AsCurrency;
  3666. cdsStatTotalYsCountTotal.AsInteger := aqStatTotalYsCountTotal.AsInteger;
  3667. cdsStatTotalQdCountTotal.AsInteger := aqStatTotalQdCountTotal.AsInteger;
  3668. cdsStatTotalResultMarkTotal.AsCurrency := aqStatTotalResultMarkTotal.AsCurrency;
  3669. cdsStatTotalAdditionalMark.AsCurrency := aqStatTotalAdditionalMark.AsCurrency;
  3670. cdsStatTotalQualityMark.AsCurrency := aqStatTotalQualityMark.AsCurrency;
  3671. cdsStatTotal.Post;
  3672. aqStatTotal.Next;
  3673. end;
  3674. // 分章节统计
  3675. aqStat.Close;
  3676. aqStat.Open;
  3677. // 旧项目的ChapterID值没有处理,都为0,GradeStat表需要ChapterID值作为主键。
  3678. // 这种情况下需要先调用Grade方法生成ChapterID值。
  3679. if aqStatChapterID.AsInteger = 0 then
  3680. exit;
  3681. cdsStat.First;
  3682. while not cdsStat.Eof do
  3683. cdsStat.Delete;
  3684. aqStat.First;
  3685. while not aqStat.Eof do
  3686. begin
  3687. cdsStat.Append;
  3688. cdsStatChapterID.AsInteger := aqStatChapterID.AsInteger;
  3689. cdsStatCode.AsString := aqStatCode.AsString;
  3690. cdsStatName.AsString := aqStatName.AsString;
  3691. cdsStatStandardGrade.AsCurrency := aqStatStandardGrade.AsCurrency;
  3692. cdsStatDeductGrade.AsCurrency := aqStatDeductGrade.AsCurrency;
  3693. cdsStatYsCount.AsInteger := aqStatYsCount.AsInteger;
  3694. cdsStatQdCount.AsInteger := aqStatQdCount.AsInteger;
  3695. cdsStatActureMark.AsCurrency := aqStatActureMark.AsCurrency;
  3696. cdsStatTotalMark.AsCurrency := aqStatTotalMark.AsCurrency;
  3697. cdsStatStdMarkPercent.AsCurrency := aqStatStdMarkPercent.AsCurrency;
  3698. cdsStatResultMark.AsCurrency := aqStatResultMark.AsCurrency;
  3699. cdsStat.Post;
  3700. aqStat.Next;
  3701. end;
  3702. if Assigned(FOnStat) then
  3703. FOnStat(aqStatTotalAdditionalMark.AsCurrency, aqStatTotalYsCountTotal.AsInteger, aqStatTotalQdCountTotal.AsInteger);
  3704. cdsStat.EnableControls;
  3705. end;
  3706. procedure TDMDataBase.cdsOrgBillsDeductGradeGetText(Sender: TField;
  3707. var Text: String; DisplayText: Boolean);
  3708. begin
  3709. if Sender.AsCurrency = 0 then
  3710. Text := ''
  3711. else if Sender.AsCurrency > 0 then
  3712. Text := '+' + CurrToStr(Sender.AsCurrency)
  3713. else
  3714. Text := CurrToStr(Sender.AsCurrency);
  3715. end;
  3716. procedure TDMDataBase.SyncGradeFromTreeNodeToDataSet(AItem: TScBillsItem);
  3717. begin
  3718. if cdsBills.Locate('ID', AItem.ID, []) then
  3719. begin
  3720. FNeedSyncTree := False;
  3721. cdsBills.Edit;
  3722. cdsBillsErrorHint.AsString := AItem.ErrorHint;
  3723. cdsBillsIsSuperscale.AsBoolean := AItem.IsSuperscale;
  3724. cdsBillsStandardGrade.AsCurrency := AItem.StandardGrade;
  3725. cdsBillsDeductGrade.AsCurrency := AItem.DeductGrade;
  3726. cdsBillsIsIgNore.AsBoolean := AItem.IsIgNore;
  3727. cdsBillsUserModified.AsBoolean := AItem.UserModified;
  3728. cdsBillsLostPreSiblingCount.AsInteger := AItem.LostPreSiblingCount;
  3729. cdsBillsLostChildrenCount.AsInteger := AItem.LostNextSiblingCount;
  3730. cdsBillsLostNextSiblingCount.AsInteger := AItem.LostNextSiblingCount;
  3731. cdsBillsNameErrorFlag.AsInteger := AItem.NameErrorFlag;
  3732. cdsBillsUnitsErrorFlag.AsInteger := AItem.UnitsErrorFlag;
  3733. cdsBillsRightName.AsString := AItem.RightName;
  3734. cdsBillsRightUnits.AsString := AItem.RightUnits;
  3735. if cdsBillsChapterID.AsInteger <> AItem.ChapterID then
  3736. cdsBillsChapterID.AsInteger := AItem.ChapterID;
  3737. cdsBills.Post;
  3738. FNeedSyncTree := True;
  3739. end;
  3740. end;
  3741. procedure TDMDataBase.SetUserModifiedGrade;
  3742. begin
  3743. cdsOrgBills.Edit;
  3744. cdsOrgBillsUserModified.AsBoolean := True;
  3745. cdsOrgBills.Post;
  3746. end;
  3747. procedure TDMDataBase.SyncGradeFromDataSetToTreeNode(ACDS: TClientDataSet);
  3748. var vItem: TScBillsItem;
  3749. begin
  3750. vItem := FBillsTree[ACDS.FieldByName('ID').AsInteger];
  3751. if Assigned(vItem) then
  3752. begin
  3753. vItem.Code := ACDS.FieldByName('Code').asString;
  3754. vItem.B_Code := ACDS.FieldByName('B_Code').asString;
  3755. vItem.Name := ACDS.FieldByName('Name').asString;
  3756. vItem.Units := ACDS.FieldByName('Units').AsString;
  3757. vItem.Quantity := ACDS.FieldByName('Quantity').AsFloat;
  3758. vItem.DesignQuantity := ACDS.FieldByName('DesignQuantity').AsFloat;
  3759. vItem.DesignQuantity2 := ACDS.FieldByName('DesignQuantity2').AsFloat;
  3760. vItem.ErrorHint := ACDS.FieldByName('ErrorHint').AsString;
  3761. vItem.IsSuperscale := ACDS.FieldByName('IsSuperscale').AsBoolean;
  3762. vItem.StandardGrade := ACDS.FieldByName('StandardGrade').AsCurrency;
  3763. vItem.DeductGrade := ACDS.FieldByName('DeductGrade').AsCurrency;
  3764. vItem.IsIgNore := ACDS.FieldByName('IsIgNore').AsBoolean;
  3765. vItem.UserModified := ACDS.FieldByName('UserModified').AsBoolean;
  3766. vItem.LostPreSiblingCount := ACDS.FieldByName('LostPreSiblingCount').AsInteger;
  3767. vItem.LostNextSiblingCount := ACDS.FieldByName('LostChildrenCount').AsInteger;
  3768. vItem.LostNextSiblingCount := ACDS.FieldByName('LostNextSiblingCount').AsInteger;
  3769. vItem.NameErrorFlag := ACDS.FieldByName('NameErrorFlag').AsInteger;
  3770. vItem.UnitsErrorFlag := ACDS.FieldByName('UnitsErrorFlag').AsInteger;
  3771. vItem.RightName := ACDS.FieldByName('RightName').AsString;
  3772. vItem.RightUnits := ACDS.FieldByName('RightUnits').AsString;
  3773. vItem.IsAccQuantity := ACDS.FieldByName('IsAccQuantity').AsBoolean;
  3774. end;
  3775. end;
  3776. procedure TDMDataBase.cdsBillsLostNextSiblingCountChange(Sender: TField);
  3777. begin
  3778. Sender.Tag := 1;
  3779. end;
  3780. procedure TDMDataBase.cdsOrgBillsLostNextSiblingCountChange(
  3781. Sender: TField);
  3782. begin
  3783. Sender.Tag := 1;
  3784. end;
  3785. procedure TDMDataBase.aqStatCalcFields(DataSet: TDataSet);
  3786. var cSGT: Currency;
  3787. begin
  3788. if aqStatStandardGrade.AsCurrency = 0 then
  3789. aqStatActureMark.AsCurrency := 0
  3790. else
  3791. aqStatActureMark.AsCurrency := (aqStatStandardGrade.AsCurrency +
  3792. aqStatDeductGrade.AsCurrency) / aqStatStandardGrade.AsCurrency * 100;
  3793. aqStatTotalMark.AsCurrency := 100;
  3794. if aqStatTotal.RecordCount > 0 then
  3795. cSGT := aqStatTotalStandardGradeTotal.AsCurrency
  3796. else
  3797. cSGT := 0;
  3798. if cSGT = 0 then
  3799. aqStatStdMarkPercent.AsCurrency := 0
  3800. else
  3801. aqStatStdMarkPercent.AsCurrency := aqStatStandardGrade.AsCurrency / cSGT * 100;
  3802. aqStatResultMark.AsCurrency := aqStatActureMark.AsCurrency * aqStatStdMarkPercent.AsCurrency / 100;
  3803. end;
  3804. function TDMDataBase.LooseCompareIsSame(AStr1, AStr2: string): Boolean;
  3805. begin
  3806. AStr1 := Trim(AStr1);
  3807. AStr2 := Trim(AStr2);
  3808. // 识别全角、半角括号:()()
  3809. AStr1 := StringReplace(AStr1, '(', '(', [rfReplaceAll]);
  3810. AStr1 := StringReplace(AStr1, ')', ')', [rfReplaceAll]);
  3811. AStr2 := StringReplace(AStr2, '(', '(', [rfReplaceAll]);
  3812. AStr2 := StringReplace(AStr2, ')', ')', [rfReplaceAll]);
  3813. if SameText(AStr1, AStr2) then
  3814. Result := True
  3815. else
  3816. Result := False;
  3817. end;
  3818. function TDMDataBase.GetHasGatherQ: Boolean;
  3819. var iID: Integer;
  3820. begin
  3821. Result := False;
  3822. iID := cdsOrgBillsID.AsInteger;
  3823. cdsDrawingQuantity.Filter := 'BillsID=' + IntToStr(iID);
  3824. cdsDrawingQuantity.Filtered := True;
  3825. try
  3826. cdsDrawingQuantity.First;
  3827. while not cdsDrawingQuantity.Eof do
  3828. begin
  3829. if cdsDrawingQuantityIsGatherQ.AsBoolean = True then
  3830. begin
  3831. Result := True;
  3832. Break;
  3833. end;
  3834. cdsDrawingQuantity.Next;
  3835. end;
  3836. finally
  3837. cdsDrawingQuantity.Filtered := False;
  3838. end;
  3839. end;
  3840. // 生成SerialNo、ChapterID、FullCode
  3841. procedure TDMDataBase.Save_SerialNo_ChapterID_FullCode;
  3842. var
  3843. iSerialNo, iChapterID: Integer;
  3844. strFullCode, sBCodeAlpha: string;
  3845. bIsLeaf: Boolean;
  3846. function GetChapterID(vNode: TZjIDTreeNode): Integer;
  3847. begin
  3848. while (vNode.Level > 1) do
  3849. vNode := vNode.Parent;
  3850. Result := vNode.ID;
  3851. end;
  3852. function IsNecessary: Boolean;
  3853. begin
  3854. Result := (cdsBillsSerialNo.AsInteger <> iSerialNo) or
  3855. (cdsBillsFullCode.AsString <> strFullCode) or
  3856. (cdsBillsChapterID.AsInteger <> iChapterID) or
  3857. (cdsBillsIsLeaf.AsBoolean <> bIsLeaf) or
  3858. (cdsBillsB_CodeAlpha.AsString <> sBCodeAlpha);
  3859. end;
  3860. procedure SaveSerialnoAndFullCodeAndChapterIDAndIsLeaf;
  3861. begin
  3862. cdsBills.Edit;
  3863. cdsBillsSerialNo.AsInteger := iSerialNo;
  3864. cdsBillsFullCode.AsString := strFullCode;
  3865. cdsBillsChapterID.AsInteger := iChapterID;
  3866. cdsBillsIsLeaf.AsBoolean := bIsLeaf;
  3867. cdsBillsB_CodeAlpha.AsString := sBCodeAlpha;
  3868. cdsBills.Post;
  3869. end;
  3870. procedure SaveIfNecessary;
  3871. begin
  3872. if IsNecessary then
  3873. SaveSerialnoAndFullCodeAndChapterIDAndIsLeaf;
  3874. end;
  3875. procedure PrepareSerialnoAndFullCodeAndChapterIDAndIsLeaf(ANode: TZjIDTreeNode);
  3876. begin
  3877. iSerialNo := ANode.MajorIndex;
  3878. strFullCode := GetBillsFullCode(ANode.ID);
  3879. sBCodeAlpha := FormatBCodeAlpha(TScBillsItem(ANode).B_Code);
  3880. iChapterID := GetChapterID(ANode);
  3881. bIsLeaf := not ANode.HasChildren;
  3882. end;
  3883. procedure PrepareAndSave(ANode: TZjIDTreeNode);
  3884. begin
  3885. if cdsBills.FindKey([ANode.ID]) then
  3886. begin
  3887. PrepareSerialnoAndFullCodeAndChapterIDAndIsLeaf(ANode);
  3888. SaveIfNecessary;
  3889. end;
  3890. end;
  3891. var
  3892. I, iCurID: Integer;
  3893. begin
  3894. // TimeBegin('Save_SerialNo_ChapterID_FullCode');
  3895. iCurID := cdsOrgBillsID.AsInteger;
  3896. CloneActive(False);
  3897. FEnabledUITreeEvt(False);
  3898. try
  3899. for I := 0 to FBillsTree.Count - 1 do
  3900. PrepareAndSave(FBillsTree.Items[I]);
  3901. finally
  3902. FEnabledUITreeEvt(True);
  3903. CloneActive(True);
  3904. cdsOrgBills.Locate('ID', iCurID, []);
  3905. end;
  3906. // TimeEnd();
  3907. end;
  3908. procedure TDMDataBase.aqStatTotalCalcFields(DataSet: TDataSet);
  3909. var cAddMark: Currency;
  3910. begin
  3911. if aqStatTotalStandardGradeTotal.AsCurrency = 0 then
  3912. aqStatTotalResultMarkTotal.AsCurrency := 0
  3913. else
  3914. aqStatTotalResultMarkTotal.AsCurrency := (aqStatTotalStandardGradeTotal.AsCurrency +
  3915. aqStatTotalDeductGradeTotal.AsCurrency) / aqStatTotalStandardGradeTotal.AsCurrency * 100;
  3916. cAddMark := FloatToCurr(aqStatTotalYsCountTotal.AsInteger / 5 + aqStatTotalQdCountTotal.AsInteger / 50);
  3917. if cAddMark > 5 then
  3918. cAddMark := 5;
  3919. aqStatTotalAdditionalMark.AsCurrency := cAddMark;
  3920. aqStatTotalQualityMark.AsCurrency := aqStatTotalResultMarkTotal.AsCurrency + cAddMark;
  3921. end;
  3922. procedure TDMDataBase.ClearAllUnitPrices;
  3923. begin
  3924. cdsBills.First;
  3925. while not cdsBills.Eof do
  3926. begin
  3927. if cdsBillsUnitPrice.AsCurrency <> 0 then
  3928. begin
  3929. cdsBills.Edit;
  3930. cdsBillsUnitPrice.AsCurrency := 0;
  3931. cdsBills.Post;
  3932. end;
  3933. cdsBills.Next;
  3934. end;
  3935. end;
  3936. procedure TDMDataBase.cdsOrgDrawingQuantityAfterDelete(DataSet: TDataSet);
  3937. begin
  3938. // Modified by GiLi 2012-3-19 10:40:46
  3939. // 未勾选填工程量,删除细目也删除Bills清单量的BUG
  3940. GatherDQQty(cdsOrgBillsID.AsInteger, FCurIsGatherQ);
  3941. end;
  3942. procedure TDMDataBase.GatherBillsQuantity;
  3943. procedure GatherQuantityIfNotHasChildren(ANode: TZjIDTreeNode);
  3944. begin
  3945. if not ANode.HasChildren then
  3946. GatherDQQty(ANode.ID, False);
  3947. end;
  3948. var
  3949. I: Integer;
  3950. begin
  3951. for I := 0 to FBillsTree.Count - 1 do
  3952. GatherQuantityIfNotHasChildren(FBillsTree.Items[I]);
  3953. end;
  3954. function TDMDataBase.GetBQStdTreeFile: string;
  3955. begin
  3956. Result := FBQStdTreeFile;
  3957. end;
  3958. function TDMDataBase.GetPBStdTreeFile: string;
  3959. begin
  3960. Result := FPBStdTreeFile;
  3961. end;
  3962. procedure TDMDataBase.ReadBillGradeStdFile;
  3963. var vIni: TIniFile;
  3964. sPath: string;
  3965. begin
  3966. sPath := ExtractFilePath(Application.ExeName);
  3967. // 造价软件是SmartCostBD.ini。这里使用的“项目清单20XX版.dat”跟造价程序不共用。
  3968. // 因为我发现它们的表结构不一致,只好分开。 chenshilong
  3969. vIni := TIniFile.Create(sPath + 'config.ini');
  3970. try
  3971. FPBStdTreeFile := sPath + vIni.ReadString('BillsGrade', 'ProjectBillLib', 'Data\项目清单20XX版.dat');
  3972. FBQStdTreeFile := sPath + vIni.ReadString('BillsGrade', 'QuantityBillLib', 'Data\工程量清单20XX版.dat');
  3973. finally
  3974. vIni.Free;
  3975. end;
  3976. end;
  3977. procedure TDMDataBase.ClearBillsFieldsTagAfterHandle;
  3978. begin
  3979. cdsOrgBillsParentID.Tag := 0;
  3980. cdsOrgBillsNextSiblingID.Tag := 0;
  3981. cdsOrgBillsCode.Tag := 0;
  3982. cdsOrgBillsB_Code.Tag := 0;
  3983. cdsOrgBillsName.Tag := 0;
  3984. cdsOrgBillsUnits.Tag := 0;
  3985. end;
  3986. function TDMDataBase.IsContainXXItem(ACode: string): Boolean;
  3987. var
  3988. I, J: Integer;
  3989. // sCurItem, sBaseItem: string;
  3990. // iBaseSize, iCurSize: Integer;
  3991. sPreACode1, sPreACode2, sPreACode, sPrePCode: string;
  3992. iACodeLen, i_Count: Integer;
  3993. begin
  3994. // Modified by GiLi 2012-5-2 11:07:45
  3995. // 识别1-5-6-n 不进行汇总
  3996. // Result := False;
  3997. // sBaseItem := '1-5-6';
  3998. // ACode := GetPreCode(ACode);
  3999. // iBaseSize := Length(sBaseItem);
  4000. // for I := 0 to FGatherXXItems.Count - 1 do
  4001. // begin
  4002. // sCurItem := FGatherXXItems[I];
  4003. // iCurSize := Length(sCurItem);
  4004. // if iCurSize > iBaseSize then
  4005. // begin
  4006. // sCurItem := LeftStr(sCurItem, iBaseSize);
  4007. // if SameText(sCurItem, sBaseItem) then
  4008. // begin
  4009. // Result := True;
  4010. // Break;
  4011. // end;
  4012. // end;
  4013. // if (ACode = FGatherXXItems[I]) then
  4014. // begin
  4015. // Result := True;
  4016. // Break;
  4017. // end;
  4018. // end;
  4019. // chenshilong, 2012-09-11
  4020. Result := False;
  4021. iACodeLen := Length(ACode);
  4022. // 取前缀:如1-5-6-8,结果1-5-6-
  4023. for J := iACodeLen downto 1 do
  4024. begin
  4025. if ACode[J] = '-' then
  4026. begin
  4027. sPreACode1 := Copy(ACode, 1, J);
  4028. Break;
  4029. end;
  4030. end;
  4031. // 取掩码前缀:如1-5-6-8,结果1-5-m-
  4032. i_Count := 0;
  4033. for J := iACodeLen downto 1 do
  4034. begin
  4035. if ACode[J] = '-' then
  4036. begin
  4037. Inc(i_Count);
  4038. if i_Count = 2 then
  4039. begin
  4040. sPreACode2 := Copy(ACode, 1, J) + 'm-';
  4041. Break;
  4042. end;
  4043. end;
  4044. end;
  4045. for I := 0 to FGatherXXItems.Count - 1 do
  4046. begin
  4047. sPrePCode := FGatherXXItems[I] + '-';
  4048. if Pos('m', sPrePCode) > 0 then
  4049. sPreACode := sPreACode2
  4050. else
  4051. sPreACode := sPreACode1;
  4052. if sPreACode = sPrePCode then
  4053. begin
  4054. Result := True;
  4055. Break;
  4056. end;
  4057. end;
  4058. end;
  4059. function TDMDataBase.HasSelected: Boolean;
  4060. var
  4061. I: Integer;
  4062. begin
  4063. Result := False;
  4064. for I := 0 to FBillsTree.Count - 1 do
  4065. begin
  4066. if TScBillsItem(FBillsTree.Items[I]).Selected then
  4067. begin
  4068. Result := True;
  4069. Break;
  4070. end;
  4071. end;
  4072. end;
  4073. procedure TDMDataBase.ClearBlankGatherXXItems;
  4074. var
  4075. I: integer;
  4076. begin
  4077. for I := FGatherXXItems.Count - 1 downto 0 do
  4078. if FGatherXXItems[I] = '' then
  4079. FGatherXXItems.Delete(I);
  4080. end;
  4081. procedure TDMDataBase.RefreshByItem(AItem: TScBillsItem);
  4082. begin
  4083. if cdsOrgBills.Locate('ID', AItem.ID, []) then
  4084. begin
  4085. FNeedSyncTree := False;
  4086. cdsOrgBills.Edit;
  4087. cdsOrgBillsErrorHint.AsString := AItem.ErrorHint;
  4088. cdsOrgBillsIsSuperscale.AsBoolean := AItem.IsSuperscale;
  4089. cdsOrgBillsStandardGrade.AsCurrency := AItem.StandardGrade;
  4090. cdsOrgBillsDeductGrade.AsCurrency := AItem.DeductGrade;
  4091. cdsOrgBillsIsIgNore.AsBoolean := AItem.IsIgNore;
  4092. cdsOrgBillsUserModified.AsBoolean := AItem.UserModified;
  4093. cdsOrgBillsLostPreSiblingCount.AsInteger := AItem.LostPreSiblingCount;
  4094. cdsOrgBillsLostChildrenCount.AsInteger := AItem.LostNextSiblingCount;
  4095. cdsOrgBillsLostNextSiblingCount.AsInteger := AItem.LostNextSiblingCount;
  4096. cdsOrgBillsNameErrorFlag.AsInteger := AItem.NameErrorFlag;
  4097. cdsOrgBillsUnitsErrorFlag.AsInteger := AItem.UnitsErrorFlag;
  4098. cdsOrgBillsRightName.AsString := AItem.RightName;
  4099. cdsOrgBillsRightUnits.AsString := AItem.RightUnits;
  4100. if cdsOrgBillsChapterID.AsInteger <> AItem.ChapterID then
  4101. cdsOrgBillsChapterID.AsInteger := AItem.ChapterID;
  4102. cdsOrgBills.Post;
  4103. end;
  4104. end;
  4105. procedure TDMDataBase.DeleteLastParentUnit(AID: Integer);
  4106. procedure DeleteUnitByNode(ANode: TScBillsItem);
  4107. begin
  4108. while ANode <> nil do
  4109. begin
  4110. if ANode.Parent <> nil then
  4111. begin
  4112. if TScBillsItem(ANode.FirstChild) = nil then
  4113. begin
  4114. if TScBillsItem(ANode.Parent).B_Code <> '' then
  4115. begin
  4116. TScBillsItem(ANode.Parent).Units := '';
  4117. if cdsBills.Locate('ID', ANode.Parent.ID, []) then
  4118. begin
  4119. cdsBills.Edit;
  4120. cdsBillsUnits.AsString := '';
  4121. cdsBills.Post;
  4122. end;
  4123. if cdsOrgBills.Locate('ID', ANode.Parent.ID, []) then
  4124. begin
  4125. cdsOrgBills.Edit;
  4126. cdsOrgBillsUnits.AsString := '';
  4127. cdsOrgBills.Post;
  4128. end;
  4129. end;
  4130. end;
  4131. end;
  4132. DeleteUnitByNode(TScBillsItem(ANode.NextSibling));
  4133. ANode := TScBillsItem(ANode.FirstChild);
  4134. end;
  4135. end;
  4136. var
  4137. CurNode: TScBillsItem;
  4138. begin
  4139. CurNode := BillsTree.FindNode(AID);
  4140. DeleteUnitByNode(CurNode)
  4141. end;
  4142. procedure TDMDataBase.AccQuantityToParentItem(AParentID: Integer;
  4143. AQuantity1, AQuantity2: Double);
  4144. begin
  4145. if cdsBills.FindKey([AParentID]) then
  4146. begin
  4147. cdsBills.Edit;
  4148. cdsBillsDesignQuantity.Value := ScRoundTo(cdsBillsDesignQuantity.AsFloat + AQuantity1, -3);
  4149. cdsBillsDesignQuantity2.Value := ScRoundTo(cdsBillsDesignQuantity2.AsFloat + AQuantity2, -3);
  4150. cdsBills.Post;
  4151. if cdsBillsIsAccQuantity.AsBoolean then
  4152. AccQuantityToParentItem(cdsBillsParentID.AsInteger, AQuantity1, AQuantity2);
  4153. end;
  4154. end;
  4155. procedure TDMDataBase.CalculateParentQuantity;
  4156. var
  4157. DesignQuantity, DesignQuantity2: Double;
  4158. begin
  4159. if cdsOrgBillsB_Code.AsString = '' then
  4160. begin
  4161. {
  4162. if cdsOrgBillsIsAccQuantity.AsBoolean then
  4163. AccQuantityToParentItem(cdsOrgBillsParentID.AsInteger, cdsOrgBillsDesignQuantity.AsFloat,
  4164. cdsOrgBillsDesignQuantity2.AsFloat)
  4165. else
  4166. AccQuantityToParentItem(cdsOrgBillsParentID.AsInteger, -cdsOrgBillsDesignQuantity.AsFloat,
  4167. -cdsOrgBillsDesignQuantity2.AsFloat)
  4168. }
  4169. // 当有填父项量时,将自己的数量填到父项中
  4170. GatherChildDQuantity(cdsOrgBillsParentID.AsInteger);
  4171. // 当其本身的数量是子项通过填父项量统计而来时,修改本身的值不允许,
  4172. // 但是前面也没做处理,所以在这里做处理:将本身的值通过子项的
  4173. // 填父项量在统计一般
  4174. GatherChildDQuantity(cdsOrgBillsID.AsInteger);
  4175. end;
  4176. end;
  4177. function TDMDataBase.HasCalcPQChildItem(ABillsID: Integer): Boolean;
  4178. var
  4179. vItem, vChildItem: TScBillsItem;
  4180. I: Integer;
  4181. begin
  4182. Result := False;
  4183. vItem := BillsTree.BillsItem[ABillsID];
  4184. if vItem.HasChildren then
  4185. begin
  4186. for I := 0 to vItem.ChildCount - 1 do
  4187. begin
  4188. vChildItem := TScBillsItem(vItem.ChildNodes[I]);
  4189. if vChildItem.IsAccQuantity then
  4190. begin
  4191. Result := True;
  4192. Exit;
  4193. end;
  4194. end;
  4195. end;
  4196. end;
  4197. procedure TDMDataBase.CancelChildItemIsAQ(ABillsID: Integer);
  4198. var
  4199. vItem, vChildItem: TScBillsItem;
  4200. I, ChildID: Integer;
  4201. begin
  4202. FOnCancelIsAQ := True;
  4203. vItem := BillsTree.BillsItem[ABillsID];
  4204. if vItem.HasChildren then
  4205. begin
  4206. for I := 0 to vItem.ChildCount - 1 do
  4207. begin
  4208. vChildItem := TScBillsItem(vItem.ChildNodes[I]);
  4209. ChildID := vChildItem.ID;
  4210. if cdsBills.FindKey([ChildID]) then
  4211. begin
  4212. cdsBills.Edit;
  4213. cdsBillsIsAccQuantity.AsBoolean := False;
  4214. cdsBills.Post;
  4215. end;
  4216. end;
  4217. end;
  4218. FOnCancelIsAQ := False;
  4219. end;
  4220. procedure TDMDataBase.cdsOrgBillsIsAccQuantityChange(Sender: TField);
  4221. begin
  4222. if not FOnCancelIsAQ then
  4223. Sender.Tag := 1;
  4224. end;
  4225. procedure TDMDataBase.GatherChildDQuantity(ABillsID: Integer);
  4226. var
  4227. vItem, vChildItem: TScBillsItem;
  4228. I: Integer;
  4229. DesignQuantity, DesignQuantity2: Double;
  4230. begin
  4231. DesignQuantity := 0;
  4232. DesignQuantity2 := 0;
  4233. vItem := BillsTree.BillsItem[ABillsID];
  4234. if vItem = nil then
  4235. Exit;
  4236. for I := 0 to vItem.ChildCount - 1 do
  4237. begin
  4238. vChildItem := TScBillsItem(vItem.ChildNodes[I]);
  4239. if vChildItem.IsAccQuantity then
  4240. begin
  4241. DesignQuantity := ScRoundTo(DesignQuantity + vChildItem.DesignQuantity, -3);
  4242. DesignQuantity2 := ScRoundTo(DesignQuantity2 + vChildItem.DesignQuantity2, -3);
  4243. end;
  4244. end;
  4245. if (cdsBills.FindKey([ABillsID])) and ((DesignQuantity <> 0) or (DesignQuantity2 <> 0)) then
  4246. begin
  4247. cdsBills.Edit;
  4248. cdsBillsDesignQuantity.AsFloat := DesignQuantity;
  4249. cdsBillsDesignQuantity2.AsFloat := DesignQuantity2;
  4250. cdsBills.Post;
  4251. end;
  4252. end;
  4253. function TDMDataBase.FindIDRecord(AItems: TList; AID: Integer): PIDRecord;
  4254. var
  4255. I: Integer;
  4256. begin
  4257. for I := 0 to AItems.Count - 1 do
  4258. begin
  4259. Result := AItems[I];
  4260. if Result.NextID = AID then
  4261. Exit;
  4262. end;
  4263. Result := nil;
  4264. end;
  4265. procedure TDMDataBase.CloneActive(IsActive: Boolean);
  4266. begin
  4267. // cdsOrgBills.Active := IsActive; 恢复后少数据
  4268. // cdsBillsLookup.Active := IsActive;
  4269. // cdsXMJBills.Active := IsActive; 这句会报错
  4270. // MainFrm.StdBillsCtrl.DMStdBillsLib.CloneActive(IsActive);
  4271. if IsActive then
  4272. begin
  4273. cdsOrgBills.CloneCursor(cdsBills, True);
  4274. cdsBillsLookup.CloneCursor(cdsBills, True);
  4275. EnterXMJBills;
  4276. end
  4277. else
  4278. begin
  4279. cdsOrgBills.Active := IsActive;
  4280. cdsBillsLookup.Active := IsActive;
  4281. LeaveXMJBills;
  4282. end;
  4283. end;
  4284. end.