| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818 |
- {*******************************************************************************
- 单元名称: ScXMLPort.pas
- 单元说明: 导入、导出 XML文件接口。
- 作者时间: Chenshilong, 2013-06-18
- *******************************************************************************}
- unit ScXMLPort;
- interface
- uses
- SysUtils, Classes, DB, ADODB, Forms, ScConsts, NativeXml,
- ScProjectUnitPriceLibsUnit, ScProjectFeeRateLibsUnit, ScProjBaseDM,
- ScBillsDM, DBClient, ScRations, ScGroundCompensateDM, ScBaseTreeDM, sdDB;
- const OpenWHPort = {True;//}False; // 是否开放芫湖接口
- const OpenCZPort = {True;//}False; // 是否开放安徽接口 (池州)
- type
- TProcedure = procedure(AValue: Double) of object;
- TFunction = function(): Double of object;
- TArea = (areaZheJiang, areaChiZhou);
- PXMLNode = ^TXMLNodeRec;
- TXMLNodeRec = record
- Data: TXmlNode;
- FullCode: string;
- end;
- TXMLPort = class(TObject) // XML通用导出接口
- private
- FXMLDoc: TNativeXml;
- FRoot: TXmlNode;
- FFileType: TxmlFileType; // 招标,投标, 控制价。
- FRootName: string; // 编办地区。(一些地区导出的内容大部分相同,仅少量不同,代码上公用使用这个属性来区分)
- FArea: TArea;
- FXMLFile: string; // 输出的最终XML文件
- FBuildProjRec: TsdDataRecord; // 建设项目。
- FProject: TObject;
- FTenderRecList: TList; // 多项目。从此属性获取。但为兼容,旧接口可以直接从FProject取。
- FBillsTree: TScBillsTree;
- FQuery1: TADOQuery;
- FQuery2: TADOQuery; // 用于第二层嵌套,如定额
- FQuery3: TADOQuery; // 用于第三层嵌套,如工料机
- FQuery4: TADOQuery; // 用于第四层嵌套,如材料计算之原价计算
- FQuery5: TADOQuery; // 用于第五层嵌套,如原价计算下的定额
- FSearch1: TADOQuery; // 用于临时查询1
- FSearch2: TADOQuery; // 用于临时查询2
- FSearch3: TADOQuery; // 用于临时查询3
- FSearch4: TADOQuery; // 用于临时查询4
- FUnitPriceFile: TScProjectUnitPriceLib;
- FFeeRateFile: TScProjectFeeRateLib;
- FSerialNoOfID2: Integer; // ID为2的清单的 SerialNo
- FXMLNodesList: TList;
- FB_CodeFieldName: string;
- FProgressive: Boolean;
- FProgressiveFile: string;
- {---------------------------------------------------------------------------
- 存储内容:'Key=Code',如:'535-4-1-25.6=1511010-1'
- 分号前:4项合成的Key:GLJID-Type-CalculateType-RationPrice
- 分号后:新编号:Code-后缀。因同一工料机重复,修改成新编号,递增后缀。
- 由于 Delphi 找不到字符串到字符串的映射结构(二维数组不能动态定义),
- 这里用TStringList曲线救国。
- ----------------------------------------------------------------------------}
- FGLJKeyCodeMap: TStringList;
- FFirtProjIsNewOpen: Boolean;
- FProgressive2: Boolean;
- FProjectInfoCacheList: TStringList;
- FAllProjectsTotalPriceSum: Double;
- FOnOpenProject: TNotifyEvent; // 所有标段的总造价之和
- procedure AddRoot; virtual; // 兼容旧代码
- procedure AddDetail; virtual; // 兼容旧代码
- procedure AddNodes; virtual; // 新代码使用,替代AddRoot、AddDetail:开始添加内容(通常是建设项目级的内容,多标段循环外部)
- procedure SetProject(const Value: TObject);
- // 从数据表挑选指定字段的数据,挂载到XML文件的结点AXMLNode之下。AFlag: 标记,有的需要特殊处理一下。
- procedure AddTabToXML(AQuery: TADOQuery; ASQL: string; AXMLNode: TXmlNode; ATableName, AItemName: string; AFlag: string = '');
- function IDtoSerialNo(AID: Integer): Integer; // 根据清单ID查询SerialNo
- function ChangeUnit_m3(AUnit: string): string; // 单位立方米符号要转换成m3
- function GetZJByName(AName: string): string; // 获取章节号:100~1300.
- function GetZJ(AFullCode, AName: string): string; // 209-5 是 200
- function GetSeparatorCount(ACode: string): Integer; // 获取"-"的个数
- function GetProjectTotalPrice: string; // 获取总造价
- function DoSearch(ASQL, AResultFieldName: string; ADefaultValue: string = ''): string;
- function PV(AName: string; ADefault: string = ''): string; // 取属性值,代码简写
- function PD: TScProjBaseData; // 取TScProjBaseData值,代码简写
- function BV(AName: string): string; // 取建设项目属性
- function HasTable(ATabName: string): Boolean;
- function Rec(ANode: TScBillsItem; AName: string): string;
- function BillNode(AID: Integer): TScBillsItem;
- function CheckNull(Value: string): string; overload;
- function CheckNull(Value: string; defaultValue: string): string; overload;
- function CheckNull(Value: Double): string; overload;
- function CheckBool(Value: string): string;
- function GetCompareFullCode(AItem: TScBillsItem): string; overload;
- function GetCompareFullCode(AXMLNode: TXmlNode): string; overload;
- procedure AnalyzeQZZH(AZH: string; var AQ, AZ: string); // 解析起止桩号
- function ExtractNumbers(AStr: String):Double;
- procedure CalcBillsFees(AItem: TScBillsItem);
- // 从不同的软件导出的XML中,B_Code有被写成b_Code的,需要处理
- procedure CheckB_CodeFieldName;
- procedure SetProgressive(const Value: Boolean);
- procedure SetProgressiveFile(const Value: string);
- procedure CheckProj;
- procedure SetProgressive2(const Value: Boolean);
- procedure AddMultiProjects; virtual; // 添加多个标段。每个子类使用的位置不固定(一个建设项目下有多个标段)
- // 继续为每个标段追加内容。需要子类覆盖(多标段循环内部使用,即在AddMultiProjects内使用)n: 第几个标段,序号,有时内部方法会用到。
- procedure AddNodesForEveryProject(n: Integer); virtual;
- procedure CreateProjGLJNewCodeMap; // 创建工料机新编号映射
- procedure Create_Port_Prj; // 创建新的ProjectGLJ表(原因见定义处的详细说明)。
- function GetProjectGUID(AIsBuildProj: Boolean = False): string;
- function IDtoGUID(ID: Integer): string; // 接口需要GUID,我们的整数ID太短过不了评测。
- procedure RcsvAddBillItems(AProject: TObject; AParentItem: TScBillsItem; ANode: TXmlNode); // 导入:(根据Xml数据)生成Project的BillItem。
- procedure RcsvAddDayWorks(AProject: TObject; AParentItem: TScBillsItem; ANode: TXmlNode); // 导入:(根据Xml数据)生成Project的计日工部分。
- procedure SetBuildProjRec(const Value: TsdDataRecord);
- procedure SetOnOpenProject(const Value: TNotifyEvent);
- public
- constructor Create;
- destructor Destroy; override;
- procedure SaveToXML(NeedZip: Boolean = True);
- procedure LoadFromXML; virtual; // 加载xml文件到FXMLDoc对象中。需要在子类中覆盖:将FXMLDoc的数据写入Project中。
- { 功能: 将 ABDRootNode下挂的数据填充到AProject中。导入电子标接口使用。
- 参数: AProject:在后台新建的空标段。ABDRootNode:标段的根结点(Xml),如:<公路标段工程>
- 旧模式:导入前先手工打开一个标段,然后导入Xml文件进行数据覆盖,只能单个标段操作。
- 新模式:在项目管理导入xml文件,文件中的每个标段会自动生成一个Project,并将xml数据填入,支持多个标段。 }
- procedure FillData(AProject: TObject; ABDRootNode: TXmlNode);
- procedure DisposeXMLNodesList;
- procedure ZipFiles(AFileList: TStringList; AResultFileName: string);
- property BuildProjRec: TsdDataRecord read FBuildProjRec write SetBuildProjRec;
- property Project: TObject read FProject write SetProject;
- // 其它接口单项目,直接传参数FProject;全国接口(单项目或多项目),要传参数 TenderRecList。
- property TenderRecList: TList read FTenderRecList;
- property ProjectInfoCacheList: TStringList read FProjectInfoCacheList; // 打开项目后缓存一些项目的信息,避免再次使用时又要打开
- property BillsTree: TScBillsTree read FBillsTree write FBillsTree;
- property FileType: TxmlFileType read FFileType write FFileType;
- property XMLFile: string read FXMLFile write FXMLFile;
- property Progressive: Boolean read FProgressive write SetProgressive;
- property Progressive2: Boolean read FProgressive2 write SetProgressive2;
- property ProgressiveFile: string read FProgressiveFile write SetProgressiveFile;
- property FirtProjIsNewOpen: Boolean read FFirtProjIsNewOpen write FFirtProjIsNewOpen;
- property RootName: string read FRootName write FRootName;
- property Area: TArea read FArea write FArea; // 地区:不同地区在导出内容上有细微差别,用这个区分
- property OnOpenProject: TNotifyEvent read FOnOpenProject write SetOnOpenProject;
- end;
- // 全国接口,单机版→云版(原来的云南接口) 。
- TqgXMLPort = class(TXMLPort)
- private
- FSystemInfoNode: TXmlNode;
- FCostBasisNode: TXmlNode;
- FNormLibNode: TXmlNode;
- FRateNode: TXmlNode;
- FRateRaramsNode: TXmlNode;
- FRateRaramNode: TXmlNode;
- FRateValuesNode: TXmlNode;
- FRateValueNode: TXmlNode;
- FPract: TXmlNode;
- FPract_Param: TXmlNode;
- FPract_Mps: TXmlNode;
- FPract_Materials: TXmlNode;
- FPract_Mechs: TXmlNode;
- FEprjInfoNode: TXmlNode;
- FMakeInfoNode: TXmlNode;
- FParamsNode: TXmlNode;
- FItemsNode: TXmlNode;
- FIndexsNode: TXmlNode;
- // [(Value: 3; Name: '部颁公路工程预算定额(2018)'), ]
- FLibArr: array of TIdentMapEntry;
- FAllLibNames: array of string; // 每个标段的定额库ID 都是从0开始,多个标段时会出现问题,这里分开
- FGDSZDEKID: Integer; // 广东市政定额库ID,来自这个定额库的定额要特殊处理:导出接口时,定额编号前要加"D"
- procedure AddNodes; Override;
- procedure AddNodesForEveryProject(n: Integer); Override;
- procedure AddCprjInfo;
- // <CprjInfo>的7个子结点
- procedure AddDecimalOption; // <DecimalOption>
- procedure AddSystemInfo; // <SystemInfo>
- procedure AddCostBasis; // <CostBasis><NormLib> 定额库列表。
- procedure AddRationLibs; // 添加定额库
- procedure AddRate(AFileNo: Integer); // <Rate>
- procedure AddPract(AFileNo: Integer); // <Pract>
- procedure AddEprjInfo(AFileNo: Integer); // <EprjInfo>
- procedure AddIndexs; // <Indexs>
- // <Pract>的3个子结点(从项目工料机导出)
- procedure AddMps; // [1]、导出【人工】
- procedure AddMaterials; // [2]、导出【材料】
- procedure AddMechs; // [3]、导出【机械】
- procedure AddOrgPrices(AMaterialNode: TXmlNode; AMaterialID: Integer); // [2.2]、导出材料原价
- procedure AddTranFees(AMaterialNode: TXmlNode; AMaterialID: Integer); // [2.3]、导出材料运费
- procedure AddMCRations(AParentNode: TXmlNode; AType, AMaterialID, ABillID: Integer); // [2.2.1 & 2.3.1]、导出材料计算用的定额。
- procedure AddElectric(AMaterialNode: TXmlNode); // 2.4]、导出综合电价
- procedure AddFormula(ANode: TScBillsItem; AParentXMLNode: TXmlNode); // 导出清单的公式
- procedure AddRations(ANode: TScBillsItem; AParentXMLNode: TXmlNode); // 导出定额
- procedure AddBuildLoan(AParentXMLNode: TXmlNode); // 导出贷款利息
- procedure AddGC(AParentXMLNode: TXMLNode; const ABillsID: Integer); // 导出土地
- procedure AddGC2(ALeafTree: TBaseTree; AIndex1, AIndex2: Integer; AXMLNode: TXmlNode);
- procedure AddDrawQ(ANode: TScBillsItem; AParentXMLNode: TXmlNode); // 导出图纸算量
- // <EprjInfo>的子结点
- procedure AddMakeInfo;
- procedure AddParams(AFileNo: Integer);
- procedure AddItems; // 导出所有清单
- function AddItem(ANode: TScBillsItem; AParentXMLNode: TXmlNode): TXmlNode; virtual; // 导出单条清单
- function IsSpecialFormulaBill(ANode: TScBillsItem): Boolean; overload; // 投标项目, 特殊的清单,公式写死在代码里,用户也可以自定义。
- function IsSpecialFormulaBill(ABillID: Integer): Boolean; overload;
- function CanGC(ANode: TScBillsItem): Boolean; // 能否导出土地
- function GetItemTypeByCode(AItem: TScBillsItem): string;
- function GetNormLibNoByID(ALibID: Integer): string;
- // Akey: 4项合成的Key:GLJID-Type-CalculateType-RationPrice。eg: 1736-4-0-0.78=4013003-17
- // AOrgCode 工料机原编号。映射找不到时,返回原始编号。
- function GetGJLCodeByKey(AKey: string; AOrgCode: string): string;
- function GetType(AType, ACalculateType: Integer; AName: string = ''): Integer;
- function AdjustStateToPort(ARation: TScRationRecord): string; // 导出的定额调整状态,要转换成接口要求的格式。
- function OneAdjustToPort(AOneState: string; ARation: TScRationRecord): string; // 处理调整状态中的一个小分段(被分号隔开后的)。
- public
- end;
- // 招投标派系【招标、投标、控制价】
- TZTBXMLPort = class(TXMLPort)
- private
- FGCXX: TXmlNode; // 工程信息
- FZTBXX: TXmlNode; // 招投标信息
- FGLGCSJ: TXmlNode; // 公路工程数据
- FGLBDGC: TXmlNode; // 公路标段工程 1..n
- FGCLQDB: TXmlNode; // 工程量清单表
- FJRGXXB: TXmlNode; // 计日工信息表
- FZJHZB: TXmlNode; // 造价汇总表
- FRCJHZ: TXmlNode; // 人材机汇总
- FGLGCHZ: TXmlNode; // 公路工程汇总(浙江多一层,该对象是指 公路工程汇总标题)
- procedure AddNodes; Override;
- procedure AddNodesForEveryProject(n: Integer); Override;
- procedure AddGCXX;
- procedure AddZTBXX;
- procedure AddGLGCSJ;
- procedure AddGLBDGC(n: Integer);
- procedure AddGLGCHZMX;
- procedure AddBillNodes; // 导出:生成清单的XMLNode
- procedure RcsvAddBillNode(AItem: TScBillsItem; AXMLParent: TXmlNode);
- procedure AddRationNodes(ABillItem: TScBillsItem; ABillNode: TXmlNode);
- // 叶子清单下的材料汇总
- procedure AddBillMaterials(ABillItem: TScBillsItem; ABillMetNode: TXmlNode);
- procedure AddJRG;
- procedure AddZJHZMX;
- procedure AddProjGLJs;
- procedure GetZCLB(ABillName: string; var ACapter, AType: string);
- function GetDataCheckCode: string; // 计算数据校验码
- public
- end;
- // 昆明接口
- TkmXMLPort = class(TXMLPort)
- private
- FRationLibCode: string;
- FSPNode: TXmlNode; // SingleProject
- FUPNode: TXmlNode; // UnitProject
- FSN_EEBegin: Integer; // 机电备品备件部分的起始SerialNo
- FSN_ID2: Integer; // ID为2的清单的SerialNo
- FSN_BillsEnd: Integer; // 最后一条清单的SerialNo。如果没有900~1300章,则为 FSN_ID2 - 1; 如果有则为 FSN_EEBegin - 1;
- FEETotalPrice: Currency; // 机电备品备件部分金额
- FSubHint: string; // 提示信息缓存
- FSubHint2: string; // 提示信息缓存
- procedure AddBQTable; // 清单
- procedure AddNorms(ARoot: TXmlNode); // 定额
- procedure AddQuantityUnitPrice(ARoot: TXmlNode); // 数量单价
- procedure AddBQPriceAnalysisItem(ARoot: TXmlNode); // 单价分析(即我们的清单子目工料机汇总)
- procedure AddNormResUsageItem(ARoot: TXmlNode); // 项目文件-GLJList
- procedure AddDayWorkTable; // 计日工
- procedure AddMaterialTable; // 单价文件-GLJList
- procedure AddResource; // ProjectGLJ
- procedure AddMaterialProvisionalPriceTable; // 材料暂估价
- procedure AddProjEquipmentPriceTable; // 工程设备暂估价
- procedure AddProjProvisionalPriceTable; // 专业工程暂估价
- procedure AddSummary;
- procedure AddElectEquipmentTable; // 交通机电设施备品备件
- procedure EEValue(var ABeginSN: Integer; var ATotalPrice: Currency); // 云南从900章监控系统开始
- function GetEECostKind(AChapterID: Integer): string; // 1 监控系统 2 收费系统 3 通信系统 4 消防系统 5 供配电及照明系统
- procedure AddRoot; override;
- procedure AddDetail; override;
- public
- constructor Create;overload;
- procedure LoadFromXML; override;
- property RationLibCode: string read FRationLibCode write FRationLibCode;
- end;
- // 纵横接口,区别于外部公司的接口,如海德接口,昆明接口等。主要因为根结点内容、导出文件时机等有区别
- TzhXMLPort = class(TXMLPort)
- private
- procedure AddRoot; override;
- end;
- // 工料机价格信息收集上传(用户工料机、项目工料机)
- TgljXMLPort = class(TzhXMLPort)
- private
- procedure AddRoot; Override;
- procedure AddDetail; Override;
- end;
- // 为什么清单定额信息收集上传要另外写一个类,而不把方法写在工料机价格信息类
- // 里面一起操作呢?因为这部分数据庞大,分文件存放易于控制管理。
- // 清单定额信息收集上传 2014.12.1
- TbpXMLPort = class(TzhXMLPort)
- private
- procedure AddRoot; Override;
- procedure AddDetail; Override;
- end;
- // 芜湖接口
- TwhXMLPort = class(TXMLPort)
- private
- FDxgcxxNode: TXmlNode;
- FDwgcxxNode: TXmlNode;
- FQfxxNode: TXmlNode;
- FQdXmNode: TXmlNode;
- FZgClNode: TXmlNode;
- FJpClNode: TXmlNode;
- FRcjhzNode: TXmlNode;
- FJjFlbNode: TXmlNode;
- FJjFlxNode: TXmlNode;
- FJrgNode: TXmlNode;
- FBlackFontBillsNo: Integer;
- procedure AddRoot; Override;
- procedure AddDetail; Override;
- public
- end;
- // 图纸算量接口 2020.10.28
- TtzslXMLPort = class(TXMLPort)
- private
- FInfo: TXmlNode;
- FBillList: TXmlNode;
- FFirstBill: TXmlNode; // <Bills Code="1" Name="第一部分 建筑安装工程费">
- FSecondBill: TXmlNode; // <Bills Code="2" Name="第二部分 土地使用及拆迁补偿费">
- FThirdBill: TXmlNode;
- FFourthBill: TXmlNode;
- FCompareCDS: TClientDataSet; // 存放对比结构的内存表。
- FIsBills: Boolean; // 是否清单
- FXMLNodeList: TList;
- public
- function CheckXMLFile: Boolean; virtual;
- procedure AssignNode(ANode: TXmlNode; AItem: TScBillsItem);
- procedure AddRations(ANode: TXmlNode; AItem: TScBillsItem; var ASerialNo: Integer);
- procedure AddCountPrice(ANode: TXmlNode; AItem: TScBillsItem; ASerialNo: Integer);
- procedure AddEquipment(ANode: TXmlNode; AItem: TScBillsItem);
- procedure AddDQs(ANode: TXmlNode; AItem: TScBillsItem);
- procedure AddGroundCompensate(ANode: TXmlNode; AItem: TScBillsItem);
- procedure RcsvAddBills(ANode: TXmlNode; AParentItem: TScBillsItem);
- procedure LoadFromXML; override;
- procedure UpdateFromXML;
- procedure CompareFromXML(ACDS: TClientDataSet); // 根据XML文件对比造价书数量,显示变更结果
- procedure AnalyzeXMLNodesIntoList(ASelectItem: TScBillsItem);
- function SameFullCode(AXMLNodeFullCode: string; AItem: TScBillsItem): Boolean;
- procedure UpdateItem(AItem: TScBillsItem);
- procedure CompareItem(AItem: TScBillsItem);
- procedure RcsvUpdateItems(AItem: TScBillsItem);
- procedure RcsvCompareItems(AItem: TScBillsItem);
- procedure CompareDeleted; // 处理XML列表中的残余项:没匹配成功,因造价书中删除。
- function GetBillKindName(AItem: TScBillsItem): string; overload; // 分项 & 清单
- function GetBillKindName(ANode: TXmlNode): string; overload; // 分项 & 清单
- function GetRationKindName(ARec: TScRationRecord): string;
- end;
- // Excel块转成Xml文件格式
- TExcelBlockXMLPort = class(TtzslXMLPort)
- public
- function CheckXMLFile: Boolean; override;
- procedure LoadFromXML; override;
- end;
- const XftNames: array [TxmlFileType] of string = ('招标', '投标', '控制价');
- implementation
- uses ScProject, ProjectsDM,
- ScFeeRateLibsUnit, ScBills, ZjIDTree, ScProgressFrm, ScGLJLibs,
- ScBillsConsts, sdIDTree, Variants, ScConfig, ScUtils, ScPHPWeb,
- SysInfoUnit, ScProjectRationLibsUnit, ScXMLPortMap, ScTypes,
- VCLUnZip, VCLZip, EncdDecd, Controls, ShellAPI, Windows, ScExprs, PerlRegEx,
- Math, CslTimeDebug, ScRAdjusts, ScGLJ, ScXMLConsts, ScProjList, CLD_DogNoBySerialNo;
-
- {TXMLPort}
- procedure TXMLPort.SetProject(const Value: TObject);
- var vCon: TADOConnection;
- sSQL: string;
- begin
- FProject := Value;
- FBillsTree := TScProject(FProject).Bills.BillsTree;
- vCon := PD.acProject;
- FQuery1.Connection := vCon;
- FQuery2.Connection := vCon;
- FQuery3.Connection := vCon;
- FQuery4.Connection := vCon;
- FQuery5.Connection := vCon;
- FSearch1.Connection := vCon;
- FSearch2.Connection := vCon;
- FSearch3.Connection := vCon;
- FSearch4.Connection := vCon;
- FUnitPriceFile := TScProjectUnitPriceLib(TScProject(FProject).ProjectGLJ.ProjectUnitPriceLib);
- FFeeRateFile := TScProject(FProject).ProjectFeeRateLib;
- sSQL := Format('SELECT SerialNo FROM Bills WHERE ID = %d', [2]);
- FSerialNoOfID2 := StrToInt(DoSearch(sSQL, 'SerialNo', '0'));
- end;
- { 作用:从数据表挑选指定字段的数据,挂载到XML的某个结点之下。
- 参数:AQuery:干活的ADOQuery。ASQL:SQL语句。
- AXMLNode:在该XML结点下挂载数据。
- ATableName: 是否要在AXMLNode下加一层以表命名的子结点,默认空,即不加这一层。
- AItemName: AXMLNode子结点的名字
- 使用示例:
- procedure AddJjFlx;
- var sSQL: string;
- begin
- sSQL :=
- 'Select SerialNo as Bm, Name as Mc, Caption as ShuZhi ' +
- 'from FeeParams Order by SerialNo';
- AddTabToXML(FQuery2, sSQL, FJjFlxNode, '', 'JjFlxMx');
- end; }
- procedure TXMLPort.AddTabToXML(AQuery: TADOQuery; ASQL: string;
- AXMLNode: TXmlNode; ATableName, AItemName: string; AFlag: string);
- var vNode, vItemNode: TXmlNode;
- i: Integer;
- var sFN, sMN, sValue, sFullFN: string;
- begin
- AQuery.Close;
- AQuery.SQL.Clear;
- AQuery.SQL.Text := ASQL;
- AQuery.Open;
- if AQuery.RecordCount = 0 then Exit;
- if ATableName = '' then
- vNode := AXMLNode
- else
- vNode := AXMLNode.NodeNewUTF8(ATableName);
- AQuery.First;
- while not AQuery.Eof do
- begin
- vItemNode := vNode.NodeNewUTF8(AItemName);
- for i := 0 to AQuery.FieldCount - 1 do
- begin
- sFullFN := AQuery.Fields[i].FieldName;
- if IsMapFieldName(sFullFN) then
- begin
- sValue := StrMixMap(sFullFN, AQuery.Fields[i].AsString, sFN);
- vItemNode.AttributeAddUTF8(sFN, sValue);
- end
- else if SameText(sFullFN, 'Unit') then
- begin
- sValue := ChangeUnit_m3(AQuery.Fields[i].AsString);
- vItemNode.AttributeAddUTF8(sFullFN, sValue);
- end
- else if SameText(sFullFN, 'RateParamNo') then // <RateParam RateTypeNo="DJSGZJFFL" RateParamNo="9" Ratio="1"/>
- begin
- if AQuery.FieldByName('RateTypeNo').AsString = 'DJSGZJFFL' then // 冬季的下拉值要重新映射
- sValue := GetMapValue(GetMap('Map_WinterValues'), AQuery.Fields[i].AsString)
- else if AQuery.FieldByName('RateTypeNo').AsString = 'YUJSGZJFFL' then // 雨季的下拉值要重新映射
- sValue := GetMapValue(GetMap('Map_RainValues'), AQuery.Fields[i].AsString)
- else if AQuery.FieldByName('RateTypeNo').AsString = 'GYDQSGZJFFL' then // 高原的下拉值要重新映射
- sValue := GetMapValue(GetMap('Map_HighlandValues'), AQuery.Fields[i].AsString)
- else if AQuery.FieldByName('RateTypeNo').AsString = 'FSDQSGZJFFL' then // 风沙的下拉值要重新映射
- sValue := GetMapValue(GetMap('Map_SandValues'), AQuery.Fields[i].AsString)
- else if AQuery.FieldByName('RateTypeNo').AsString = 'XCGRGCSGZJFFL' then // 行车干扰的下拉值要重新映射
- sValue := GetMapValue(GetMap('Map_DriveCarValues'), AQuery.Fields[i].AsString)
- else
- begin
- if AQuery.FieldByName('RateParamNo').AsString = '计' then
- sValue := '1'
- else if AQuery.FieldByName('RateParamNo').AsString = '不计' then
- sValue := '0'
- else
- sValue := AQuery.Fields[i].AsString;
- end;
- vItemNode.AttributeAddUTF8(sFullFN, sValue);
- end
- else if SameText(sFullFN, 'RateValue') then // <RateValue CostTypeNo="TF" RateTypeNo="DJSGZJFFL" RateValue="0"/>
- begin
- if (AFlag = 'Flag_LrSj') then
- begin
- // <RateValue CostTypeNo="BJ" RateTypeNo="LRL" RateValue="0"/>
- // AQuery.Fields[0].FieldName →'CostTypeNo@Map_GetFeeKind_GS@0@2'
- // 14: ('14', '费率为0', 'BJ', '不计')
- if (AQuery.Fields[0].AsString = '14') and // 不计
- ((AQuery.FieldByName('RateTypeNo').AsString = 'LRL') or // 利润率、税率
- (AQuery.FieldByName('RateTypeNo').AsString = 'SL')) then
- sValue := '0'
- else
- sValue := AQuery.Fields[i].AsString;
- end
- else
- sValue := AQuery.Fields[i].AsString;
- vItemNode.AttributeAddUTF8(sFullFN, sValue);
- end
- else
- begin
- sValue := AQuery.Fields[i].AsString;
- vItemNode.AttributeAddUTF8(sFullFN, sValue);
- end;
- end;
- AQuery.Next;
- end;
- AQuery.Close;
- end;
- constructor TXMLPort.Create;
- begin
- inherited;
- FQuery1 := TADOQuery.Create(nil);
- FQuery2 := TADOQuery.Create(nil);
- FQuery3 := TADOQuery.Create(nil);
- FQuery4 := TADOQuery.Create(nil);
- FQuery5 := TADOQuery.Create(nil);
- FSearch1 := TADOQuery.Create(nil);
- FSearch2 := TADOQuery.Create(nil);
- FSearch3 := TADOQuery.Create(nil);
- FSearch4 := TADOQuery.Create(nil);
- FXMLDoc := TNativeXml.Create(nil);
- FXMLDoc.XmlFormat := xfReadable;
- FXMLDoc.VersionString := '1.0'; // 这里要加上,否则导出时 version 属性会在 encoding 属性后面,且不能控制。
- FXMLDoc.ExternalEncoding := seUTF8; // 这个控件最大的麻烦是,只能读取UTF-8格式的xml文件, 对GB2312识别乱码,这里设置成 seAnsi也没用,读的还是乱码。
- FRoot := FXMLDoc.Root;
- FXMLNodesList := TList.Create;
- FTenderRecList := TList.Create;
- FProjectInfoCacheList := TStringList.Create;
- FGLJKeyCodeMap := TStringList.Create;
- FFirtProjIsNewOpen := False;
- // FB_CodeFieldName := 'B_Code'; 从算量导进来的是 b_Code,这个属性要动态判断,不能写死。
- end;
- destructor TXMLPort.Destroy;
- var i: Integer;
- begin
- FQuery1.Free;
- FQuery2.Free;
- FQuery3.Free;
- FQuery4.Free;
- FQuery5.Free;
- FSearch1.Free;
- FSearch2.Free;
- FSearch3.Free;
- FSearch4.Free;
- FXMLDoc.Free;
- DisposeXMLNodesList;
- FXMLNodesList.Free;
- FTenderRecList.Free;
- FProjectInfoCacheList.Free;
- FGLJKeyCodeMap.Free;
- inherited;
- end;
- procedure TXMLPort.SaveToXML(NeedZip: Boolean);
- var
- vZip: TVCLZip;
- sOrgFullName, sNewFullName, sPath, sTitle: string;
- isTest: Boolean;
- begin
- if FFileType = null then
- sTitle := ''
- else
- sTitle := '-' + XftNames[FFileType];
- CreateProgressForm(100, '导出XML文件' + sTitle + ' >>>');
- CheckProj;
- // AddRoot、AddDetail 兼容旧代码。新代码使用 AddXMLNodes
- AddProgressForm(0, '生成根结点...');
- AddRoot;
- AddProgressForm(0, '生成明细数据...');
- AddDetail;
- // 新代码使用 AddNodes
- AddProgressForm(0, '生成XML结点数据...');
- AddNodes;
- AddProgressForm(10, '存储XML文件...');
- if FileExists(FXMLFile) then
- SysUtils.DeleteFile(FXMLFile);
- if not DirectoryExists(ExtractFileDir(FXMLFile)) then
- ForceDirectories(ExtractFileDir(FXMLFile));
- FXMLDoc.VersionString := '1.0';
- FXMLDoc.ExternalEncoding := seUTF8; // 这里设置成 seAnsi也没用,导出后的文件还是UTF-8格式。且根结点没有encoding="GB2312"属性。
- isTest := False; // 仅测试使用
- if isTest then
- begin
- FXMLDoc.SaveToFile(FXMLFile);
- CloseProgressForm;
- Exit;
- end;
- FXMLDoc.SaveToFile(FXMLFile);
- if NeedZip then
- begin
- AddProgressForm(10, '压缩加密...');
- vZip := TVCLZip.Create(nil);
- try
- sOrgFullName := FXMLFile;
- sPath := ExtractFilePath(FXMLFile);
- sNewFullName := sPath + 'main.xml';
- if FileExists(sNewFullName) then
- SysUtils.DeleteFile(PChar(sNewFullName));
- RenameFile(sOrgFullName, sNewFullName);
- vZip.FilesList.Add(sNewFullName);
- vZip.ZipName := sOrgFullName;
- vZip.Recurse := True;
- vZip.ZipComment := '纵横软件导出接口数据';
- vZip.OverwriteMode := Always;
- vZip.Zip;
- SysUtils.DeleteFile(PChar(sNewFullName));
- finally
- vZip.Free;
- end;
- end;
- CloseProgressForm;
- end;
- procedure TXMLPort.LoadFromXML;
- begin
- if not FileExists(FXMLFile) then Exit;
- CheckProj;
- FXMLDoc.LoadFromFile(FXMLFile);
- CheckB_CodeFieldName;
- end;
- function TXMLPort.IDtoSerialNo(AID: Integer): Integer;
- var sSQL: string;
- begin
- sSQL := Format('Select SerialNo from Bills where ID = %d', [AID]);
- Result := StrToInt(DoSearch(sSQL, 'SerialNo', '-1'));
- end;
- function TXMLPort.ChangeUnit_m3(AUnit: string): string;
- begin
- Result := StringReplace(AUnit, WideChar($00E0), 'm3', [rfReplaceAll,rfIgnoreCase]);
- end;
- function TXMLPort.GetZJByName(AName: string): string;
- var iPos1, iPos2: Integer;
- begin
- iPos1 := Pos('第', AName);
- iPos2 := Pos('章', AName);
- Result := Copy(AName, iPos1 + 2, iPos2 - iPos1 - 2);
- end;
- function TXMLPort.GetZJ(AFullCode, AName: string): string;
- begin
- if (AFullCode <> '') then
- Result := AFullCode[1] + '00'
- else
- Result := GetZJByName(AName);
- end;
- function TXMLPort.PV(AName: string; ADefault: string): string;
- begin
- Result := TScProject(FProject).Properties.PV[AName];
- if Result = '' then
- Result := ADefault;
- end;
- function TXMLPort.PD: TScProjBaseData;
- begin
- Result := TScProjBaseData(TScProject(FProject).ProjData);
- end;
- function TXMLPort.GetProjectTotalPrice: string;
- var iID: Integer;
- sSQL: string;
- begin
- if TScProject(FProject).ProjType = ptBills then
- iID := idProjectTotalPrice_Bills
- else
- iID := idProjectTotalPrice_Budget;
- sSQL := Format('SELECT TotalPrice FROM Bills WHERE ID = %d', [iID]);
- Result := DoSearch(sSQL, 'TotalPrice', '0');
- end;
- function TXMLPort.DoSearch(ASQL, AResultFieldName: string; ADefaultValue: string): string;
- begin
- Result := ADefaultValue;
- FSearch1.Close;
- FSearch1.SQL.Text := ASQL;
- FSearch1.Open;
- if FSearch1.RecordCount > 0 then
- Result := FSearch1.FieldByName(AResultFieldName).AsString;
- FSearch1.Close;
- end;
- function TXMLPort.HasTable(ATabName: string): Boolean;
- var
- I: Integer;
- vSL: TStringList;
- begin
- vSL := TStringList.Create;
- try
- PD.acProject.GetTableNames(vSL);
- Result := (vSL.IndexOf(ATabName) >= 0);
- finally
- vSL.Free;
- end;
- end;
- function TXMLPort.Rec(ANode: TScBillsItem; AName: string): string;
- begin
- Result := ANode.Rec.ValueByName(AName).AsString;
- end;
- function TXMLPort.BillNode(AID: Integer): TScBillsItem;
- begin
- Result := TScProject(FProject).Bills.BillsTree.BillsItem[AID];
- end;
- function TXMLPort.CheckNull(Value: string): string;
- var v: string;
- begin
- v := Trim(Value);
- if v = '' then
- Result := '0'
- else
- Result := v;
- end;
- function TXMLPort.CheckNull(Value: string; defaultValue: string): string;
- var v: string;
- begin
- v := Trim(Value);
- if v = '' then
- Result := defaultValue
- else
- Result := v;
- end;
- function TXMLPort.CheckBool(Value: string): string;
- var v: string;
- begin
- v := Value;
- if v = '' then
- v := '0'
- else
- begin
- if SameText(v, 'False') then
- v := '0'
- else //if SameText(v, 'True') then
- v := '1';
- end;
- Result := v;
- end;
- procedure TXMLPort.AnalyzeQZZH(AZH: string; var AQ, AZ: string);
- var i: Integer;
- begin
- i := Pos('~', AZH);
- if i > 0 then
- begin
- AQ := Copy(AZH, 1, i - 1);
- AZ := Copy(AZH, i + 1, Length(AZH) - i);
- end
- else
- begin
- AQ := AZH;
- AZ := '';
- end;
- end;
- function TXMLPort.ExtractNumbers(AStr: String): Double;
- var temp: String;
- i: integer;
- begin
- temp := '';
- for i := 1 to Length(AStr) do
- begin
- if (AStr[i] in ['0'..'9']) or (AStr[i] = '.') then
- temp := temp + AStr[i];
- end;
- if temp = '' then
- Result := 0
- else
- Result := StrToFloat(temp);
- end;
- procedure TXMLPort.CalcBillsFees(AItem: TScBillsItem);
- var i, j, k: Integer;
- vChild: TScBillsItem;
- vProc: TProcedure;
- vFunc1, vFunc2: TFunction;
- fTemp: Double;
- sSQL, sTemp: string;
- begin
- if AItem = nil then Exit;
- CalcBillsFees(TScBillsItem(AItem.FirstChild));
- if AItem.IsLeaf = True then
- begin
- sSQL := 'SELECT BillsItemID';
- for i := Low(G_Port_Fees) to High(G_Port_Fees) do
- begin
- sSQL := sSQL + ', Sum(' + G_Port_Fees[i] + ') as ' + G_Port_Fees[i];
- end;
- sSQL := sSQL + ' From RationCalclist where BillsItemID = ' + IntToStr(AItem.ID) + ' Group by BillsItemID';
- // 从定额来
- FSearch1.Close;
- FSearch1.SQL.Text := sSQL;
- FSearch1.Open;
- if FSearch1.RecordCount > 0 then
- begin
- // eg: AItem.LabourFee := FSearch1.FieldByName('LabourFee').AsFloat;
- // AItem.MaterialFee := FSearch1.FieldByName('MaterialFee').AsFloat; ...
- for i := Low(G_Port_Fees) to High(G_Port_Fees) do
- begin
- vProc := TProcedure(AItem.GetMethod('Set' + G_Port_Fees[i]));
- vProc(FSearch1.FieldByName(G_Port_Fees[i]).AsFloat);
- end;
- end;
- FSearch1.Close;
- end
- else
- begin
- //eg: AItem.LabourFee := 0; AItem.MaterialFee := 0;...
- for i := Low(G_Port_Fees) to High(G_Port_Fees) do
- begin
- vProc := TProcedure(AItem.GetMethod('Set' + G_Port_Fees[i]));
- vProc(0); // 全部清零
- end;
- // eg: AItem.LabourFee := AItem.LabourFee + vChild.LabourFee;
- // AItem.MaterialFee := AItem.MaterialFee + vChild.MaterialFee; ...
- for i := 0 to AItem.ChildCount - 1 do
- begin
- vChild := TScBillsItem(AItem.ChildNodes[i]);
- for j := Low(G_Port_Fees) to High(G_Port_Fees) do
- begin
- vFunc1 := TFunction(AItem.GetMethod('Get' + G_Port_Fees[j]));
- vFunc2 := TFunction(vChild.GetMethod('Get' + G_Port_Fees[j]));
- fTemp := vFunc1() + vFunc2();
- vProc := TProcedure(AItem.GetMethod('Set' + G_Port_Fees[j]));
- vProc(fTemp);
- end;
- end;
- end;
- CalcBillsFees(TScBillsItem(AItem.NextSibling));
- end;
- function TXMLPort.CheckNull(Value: Double): string;
- begin
- Result := CheckNull(FloatToStr(Value));
- end;
- procedure TXMLPort.DisposeXMLNodesList;
- var i: Integer;
- begin
- for i := 0 to FXMLNodesList.Count - 1 do
- begin
- if Assigned(PXMLNode(FXMLNodesList[i])) then
- Dispose(PXMLNode(FXMLNodesList[i])); // 释放指针
- end;
- end;
- // 工程量清单时,读取的 AItem.FullCode 只有自己编号,没有连接父项编号,不符合要求。
- function TXMLPort.GetCompareFullCode(AItem: TScBillsItem): string;
- var vCurItem: TScBillsItem;
- sCode: string;
- begin
- vCurItem := AItem;
- sCode := vCurItem.Code + vCurItem.B_Code;
- while (vCurItem.Parent <> nil) and ((TScBillsItem(vCurItem.Parent).Code + TScBillsItem(vCurItem.Parent).B_Code) <> '') do
- begin
- sCode := (TScBillsItem(vCurItem.Parent).Code + TScBillsItem(vCurItem.Parent).B_Code) + '-' + sCode;
- vCurItem := TScBillsItem(vCurItem.Parent);
- end;
- Result := sCode;
- end;
- function TXMLPort.GetCompareFullCode(AXMLNode: TXmlNode): string;
- var sCode: string;
- begin
- sCode := AXMLNode.AttributeValueByNameUTF8['Code'] + AXMLNode.AttributeValueByNameUTF8[FB_CodeFieldName];
- while (AXMLNode.Parent <> nil) and (AXMLNode.Parent.Name = 'Bills') and
- ((AXMLNode.Parent.AttributeValueByNameUTF8['Code'] + AXMLNode.Parent.AttributeValueByNameUTF8[FB_CodeFieldName]) <> '') do
- begin
- sCode := AXMLNode.Parent.AttributeValueByNameUTF8['Code'] + AXMLNode.Parent.AttributeValueByNameUTF8[FB_CodeFieldName] + '-' + sCode;
- AXMLNode := AXMLNode.Parent;
- end;
- Result := sCode;
- end;
- procedure TXMLPort.CheckB_CodeFieldName;
- //var
- // I: Integer;
- begin
- // AAAAA 换成了三方控件 NativeXml,下面这种写法玩不了
- // for I := 0 to FXMLDoc.XML.Count - 1 do
- // begin
- // if Pos('B_Code', FXMLDoc.XML[I]) > 0 then
- // begin
- // FB_CodeFieldName := 'B_Code';
- // Break;
- // end;
- // if Pos('b_Code', FXMLDoc.XML[I]) > 0 then
- // begin
- // FB_CodeFieldName := 'b_Code';
- // Break;
- // end;
- // end;
- FB_CodeFieldName := 'B_Code';
- if Pos('b_Code', FXMLDoc.WriteToString) > 0 then
- begin
- FB_CodeFieldName := 'b_Code';
- end;
- end;
- procedure TXMLPort.SetProgressive(const Value: Boolean);
- begin
- FProgressive := Value;
- end;
- procedure TXMLPort.SetProgressiveFile(const Value: string);
- begin
- FProgressiveFile := Value;
- end;
- procedure TXMLPort.CheckProj;
- var isNewOpen: Boolean;
- begin
- if (not Assigned(FProject)) and (FTenderRecList.Count > 0) then
- Project := GetProjectByTenderRec(TsdDataRecord(FTenderRecList[0]), isNewOpen); // 这里参数2打酱油,语法要求
- end;
- procedure TXMLPort.SetProgressive2(const Value: Boolean);
- begin
- FProgressive2 := Value;
- end;
- procedure TXMLPort.AddMultiProjects;
- var n: Integer;
- isNewOpen: Boolean;
- sValue, sTotalPrice: string;
- fTotalPrice: Double;
- begin
- for n := 0 to FTenderRecList.Count - 1 do
- begin
- AddProgressForm(10, Format('正在后台打开第 %d 个项目...', [n + 1]));
- Project := GetProjectByTenderRec(FTenderRecList[n], isNewOpen);
- sTotalPrice := GetProjectTotalPrice;
- fTotalPrice := StrToFloat(sTotalPrice);
- // 缓存当前打开项目的基本信息。序号;标段名称;金额;GUID
- sValue := Format('No=%d;Name=%s;TotalPrice=%s;GUID=%s',
- [n + 1, ProjectManager.TenderName(PD.ID), sTotalPrice, GetProjectGUID]);
- FProjectInfoCacheList.Add(sValue);
- FAllProjectsTotalPriceSum := FAllProjectsTotalPriceSum + fTotalPrice;
- CreateProjGLJNewCodeMap;
- AddNodesForEveryProject(n);
- // 打开项目事件
- if Assigned(FOnOpenProject) then
- FOnOpenProject(Project);
- { 第一个项目特殊,它在以下2种情况下可能是提前用后台打开过的:
- ①在导出前,要默认打开第一个项目取它的项目类型。
- ②要将FTenderRecList[0] 初始化给 FProject。
- 受第①条的影响,这里获取的isNewOpen值对第一个项目来说是不准的}
- if (n = 0) then
- begin
- if FFirtProjIsNewOpen then
- TScProjBaseData(TScProject(Project).ProjData).Close;
- end
- // 如果不是第一个项目,如果是新打开的,用完要关
- else
- begin
- if isNewOpen then
- TScProjBaseData(TScProject(Project).ProjData).Close;
- end;
- end;
- end;
- procedure TXMLPort.AddNodesForEveryProject(n: Integer);
- begin
- // nothing
- end;
- procedure TXMLPort.CreateProjGLJNewCodeMap;
- // 判断编号是否存在。两个位置判断:①项目工料机 ②新编号数组中。
- function IsExistCode(ACode: string): Boolean;
- var k: Integer;
- begin
- Result := False;
- FSearch3.Close;
- FSearch3.SQL.Text := Format('Select Code From Port_Prj WHERE Code=''%s''', [ACode]);
- FSearch3.Open;
- Result := (FSearch3.RecordCount > 0);
- FSearch3.Close;
- if (not Result) then
- begin
- for k := 0 to FGLJKeyCodeMap.Count - 1 do
- begin
- if FGLJKeyCodeMap.Values[FGLJKeyCodeMap.Names[k]] = ACode then
- begin
- Result := True;
- Break;
- end;
- end;
- end;
- end;
- procedure DealCodeWith_(var ACode: string; var ANum: Integer);
- var idx: Integer;
- sNewCode, sNum: string;
- begin
- idx := Pos('-', ACode);
- if idx = 0 then Exit;
- sNewCode := Copy(ACode, 1, idx - 1);
- sNum := Copy(ACode, idx + 1, Length(ACode) - idx);
- ACode := sNewCode;
- try
- ANum := StrToInt(sNum) + 1;
- except
- //
- end;
- end;
- procedure CutKey(AKey: string; var AID, AType, ACalcType, ARationPrice: string);
- var vSL: TStringList;
- begin
- vSL := TStringList.Create;
- try
- vSL.Delimiter := '-';
- vSL.DelimitedText := AKey;
- AID := vSL[0];
- AType := vSL[1];
- ACalcType := vSL[2];
- ARationPrice := vSL[3];
- finally
- vSL.Free;
- end;
- end;
- var
- i, iLen, n, c: Integer;
- sNewCode, sOldCode, sCode, sKey, sID, sType, sCalcType, sRPrice, sFileName, s1: string;
- bTest: Boolean;
- begin
- bTest := True; // 测试项目工料机的 Key-NewCode 映射表
- FGLJKeyCodeMap.Clear;
- AddProgressForm(10, '校验项目工料机类型,生成新的项目工料机表...');
- Create_Port_Prj;
- AddProgressForm(10, '检查项目工料机编号重复,生成KEY-新编号映射...');
- FSearch1.Close;
- FSearch1.SQL.Text := 'SELECT Code FROM Port_Prj GROUP BY Code HAVING COUNT(*) > 1';
- FSearch1.Open;
- if FSearch1.RecordCount = 0 then
- begin
- FSearch1.Close;
- Exit;
- end;
- try
- c := 0;
- FSearch1.First;
- while not FSearch1.Eof do
- begin
- Inc(c);
- sOldCode := FSearch1.FieldByName('Code').AsString;
- s1 := Format('为编号重复的工料机生成映射[%d/%d] %s', [c, FSearch1.RecordCount, sOldCode]);
- AddProgressForm(1, s1);
- FSearch2.Close;
- FSearch2.SQL.Text := Format('Select GLJID, Type, CalculateType, RationPrice from Port_Prj WHERE Code=''%s'' order by GLJID', [sOldCode]);
- FSearch2.Open;
- FSearch2.First;
- FSearch2.Next;
- n := 1;
- DealCodeWith_(sOldCode, n);
- while not FSearch2.Eof do
- begin
- sNewCode := sOldCode + '-' + IntToStr(n);
- while IsExistCode(sNewCode) do
- begin
- Inc(n);
- sNewCode := sOldCode + '-' + IntToStr(n);
- end;
- // '535-4-0=1511010-1' 2024.09.29 Key追加第4项:定额价。
- sKey := Format('%d-%d-%d-%g', [FSearch2.FieldByName('GLJID').AsInteger, FSearch2.FieldByName('Type').AsInteger,
- FSearch2.FieldByName('CalculateType').AsInteger, FSearch2.FieldByName('RationPrice').AsFloat]);
- FGLJKeyCodeMap.Add(Format('%s=%s', [sKey, sNewCode]));
- FSearch2.Next;
- end;
- FSearch1.Next;
- end;
- // 新编号写回 Port_Prj 表。
- if (FGLJKeyCodeMap.Count > 0) then
- begin
- FGLJKeyCodeMap.Sort;
- for i := 0 to FGLJKeyCodeMap.Count - 1 do
- begin
- sKey := FGLJKeyCodeMap.Names[i];
- sCode := FGLJKeyCodeMap.Values[sKey];
- CutKey(sKey, sID, sType, sCalcType, sRPrice);
- FSearch1.Close;
- FSearch1.SQL.Text := Format('update Port_Prj set Code=''%s'' where GLJID=%s and Type=%s and CalculateType=%s and RationPrice=%s',
- [sCode, sID, sType, sCalcType, sRPrice]);
- FSearch1.ExecSQL;
- end;
- if bTest then
- begin
- sFileName := ExtractFilePath(Application.ExeName) + 'UserData\' + 'GljKeyCodeMap.txt';
- FGLJKeyCodeMap.SaveToFile(sFileName);
- end;
- end;
- finally
- FSearch1.Close;
- FSearch2.Close;
- end;
- end;
- procedure TXMLPort.Create_Port_Prj;
- function CheckTable(ATableName: string): Boolean;
- var
- I: Integer;
- Names: TStringList;
- begin
- Names := TStringList.Create;
- try
- FSearch1.Connection.GetTableNames(Names);
- if Names.IndexOf(ATableName) < 0 then
- Result := False
- else
- Result := True;
- finally
- Names.Free;
- end;
- end;
- begin
- if CheckTable('Port_GR') then
- begin
- FSearch1.SQL.Clear;
- FSearch1.SQL.Add('Drop Table Port_GR');
- FSearch1.ExecSQL;
- end;
- if CheckTable('Port_Prj') then
- begin
- FSearch1.SQL.Clear;
- FSearch1.SQL.Add('Drop Table Port_Prj');
- FSearch1.ExecSQL;
- end;
- // 先修复旧数据,在正确数据的基础上才展开各种业务设计,否则后续各种困难。
- // 将 CalculateType 的 -1 全部改成 0,否则影响 Key 解析,如 1247-4--1。
- FSearch1.Close;
- FSearch1.SQL.Text := 'Update GLJList set CalculateType=0 where CalculateType=-1';
- FSearch1.ExecSQL;
- FSearch1.Close;
- FSearch1.SQL.Text := 'Update ProjectGLJ set CalculateType=0 where CalculateType=-1';
- FSearch1.ExecSQL;
- // 1、定额工料机 Gljlist 表去重。2、量价、设备 RationCalcList 表去重(创建新工料机时,固定类型:材料4,0。设备6,0)。3、二者联合。
- FSearch1.Close;
- FSearch1.SQL.Text :=
- 'Select * into Port_GR from ' +
- '(Select GLJID, Type, CalculateType, RationPrice From GLJList Group By GLJID, Type, CalculateType, RationPrice ' +
- 'union ' +
- 'select distinct GLJID, IIF(IsMECalc=true, 6, 4) as Type, CalculateType, ' +
- 'IIF(IsMECalc=true, IIF(isnull(UnitPrice), 0, UnitPrice), IIF(isnull(RationUnitDirectFee), 0, RationUnitDirectFee)) as RationPrice ' +
- 'From RationCalcList as R, projectGLJ as P where GLJID is not NULL and R.GLJID=P.ID)';
- FSearch1.ExecSQL;
- // 查找项目工料机有,而定额工料机、量价、设备都没有的,合在Port_GR中,成为全Key表,然后联合ProjectGLJ,生成最终的项目工料机表2。
- // 左多右少联合(在右创建新的项目工料机。多:指同一材料多种类型,少:项目工料机只有1条)。
- FSearch1.Close;
- FSearch1.SQL.Text :=
- 'Select * into Port_Prj from ( ' +
- 'select F.GLJID, F.Type, F.CalculateType, F.RationPrice, ' +
- 'P.Code, P.Name, P.Type as PType, P.CalculateType as PCType, P.Unit, P.Specs, P.Amount, P.BasePrice, P.BudgetPrice, ' +
- 'P.Main, P.New, P.FZAmount, P.SHRate, P.SHAmount, P.TaxFeeRate, P.DutiablePrice, ' +
- 'F.Type-P.Type as DiffT, F.CalculateType-P.CalculateType as DiffCT, F.RationPrice-P.BasePrice as DiffP from ' +
- '(Select GLJID, Type, CalculateType, RationPrice From Port_GR ' +
- 'union all ' +
- 'select ID as GLJID, Type, CalculateType, BasePrice as RationPrice from ProjectGLJ where ID not in (Select GLJID from Port_GR)) as F ' +
- 'left join ProjectGLJ as P on F.GLJID=P.ID)';
- FSearch1.ExecSQL;
- // 创建主键
- FSearch1.Close;
- FSearch1.SQL.Text := 'alter table Port_Prj add constraint PrimaryKey Primary Key (GLJID, type, CalculateType, RationPrice)';
- FSearch1.ExecSQL;
- // 创建索引
- FSearch1.Close;
- FSearch1.SQL.Text := 'Create Unique Index idxID_Type_CalcType on Port_Prj (GLJID, type, CalculateType, RationPrice)';
- FSearch1.ExecSQL;
- FSearch1.Close;
- end;
- function TXMLPort.GetProjectGUID(AIsBuildProj: Boolean): string;
- var sName: string;
- begin
- if Self.FileType = xftTB then // 投标直接读属性
- begin
- Result := PD.Properties.GUID;
- end
- else // 招标要自己造
- begin
- sName := ExtractFileName(PD.FileName);
- sName := Copy(sName, 2, Length(sName) - 2);
- Result := sName;
- if AIsBuildProj and (Length(sName) > 0) then
- begin
- Result := 'SC99' + Copy(sName, 5, 28) + '99CS';
- end;
- end;
- end;
- {-------------------------------------------------------------------------------
- GUID码 xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
- 36个字符,第1段8个字符,第2~4段4个字符,第5段12字符。
- x:表示 16 进制数字(0-9、a-f/A-F),大小写不敏感
- M:版本号(1-5),标识 GUID 的生成算法(最常用的是版本 4,随机生成)
- N:变体位(固定为 8、9、a、b 中的一个)
- -------------------------------------------------------------------------------}
- function TXMLPort.IDtoGUID(ID: Integer): string;
- var i: Integer;
- s1, s2: string;
- begin
- s1 := IntToStr(ID);
- while Length(s1) < 8 do
- begin
- s1 := '0'+ s1;
- end;
- // 多个标段时,生成的GUID不能重复:尾部留8位随机数字。
- s2 := '';
- while Length(s2) < 8 do
- begin
- s2 := s2 + IntToStr(random(10));
- end;
- Result := s1 + '-FFFF-4FFF-aFFF-FFFF' + s2;
- end;
- function TXMLPort.GetSeparatorCount(ACode: string): Integer;
- var i, L: Integer;
- begin
- Result := 0;
- L := Length(ACode);
- for i := 1 to L do
- begin
- if ACode[i] = '-' then
- Inc(Result);
- end;
- end;
- procedure TXMLPort.AddRoot;
- begin
- // nothing
- end;
- procedure TXMLPort.AddDetail;
- begin
- // nothing
- end;
- procedure TXMLPort.AddNodes;
- begin
- FRoot := FXMLDoc.Root;
- if (FRootName <> '') then
- FRoot.Name := AnsiToUtf8(FRootName);
- end;
- procedure TXMLPort.FillData(AProject: TObject; ABDRootNode: TXmlNode); // ABDRootNode: <公路标段工程>
- var vNode: TXmlNode;
- vItem: TScBillsItem;
- OldRealTimeCalc: Boolean;
- begin
- OldRealTimeCalc := TScProject(AProject).RealTimeCalc;
- try
- TScProject(AProject).RealTimeCalc := False;
- with TScProject(AProject).Bills do
- begin
- // 删除第一部分的子结点
- vItem := BillsTree[idNormalBillsRoot];
- BillsTree.DeleteChildren(vItem);
- vNode := ABDRootNode.FindNodeUTF8('工程量清单表').Elements[0];
- RcsvAddBillItems(AProject, vItem, vNode);
- // 导入计日工
- vItem := BillsTree[idDayWork];
- BillsTree.DeleteChildren(vItem);
- vNode := ABDRootNode.FindNodeUTF8('计日工信息表').Elements[0];
- RcsvAddDayWorks(AProject, vItem, vNode);
- TScProject(AProject).Bills.CalculateAll;
- // 最后存储
- TScProjBaseData(TScProject(AProject).ProjData).Save;
- end;
- finally
- TScProject(AProject).RealTimeCalc := OldRealTimeCalc;
- end;
- end;
- procedure TXMLPort.RcsvAddBillItems(AProject: TObject; AParentItem: TScBillsItem; ANode: TXmlNode);
- function AddItemMX(AProject: TObject; AParentItem: TScBillsItem; ANode: TXmlNode): TScBillsItem;
- var dt: string;
- begin
- dt := ANode.AttributeValueByNameUTF8['数据类型'];
- Result := TScProject(AProject).Bills.BillsTree.AddBillsItem(AParentItem.ID, -1);
- with Result.Rec do
- begin
- BeginUpdate;
- GUIDstr.AsString := ANode.AttributeValueByNameUTF8['GUID'];
- DataType.AsString := dt;
- Code.AsString := ANode.AttributeValueByNameUTF8['子目号'];
- Name.AsString := ANode.AttributeValueByNameUTF8['子目名称'];
- MemoStr.AsString := ANode.AttributeValueByNameUTF8['备注'];
- Units.AsString := ANode.AttributeValueByNameUTF8['单位'];
- Quantity.AsString := ANode.AttributeValueByNameUTF8['数量'];
- UnitPrice.AsString := ANode.AttributeValueByNameUTF8['单价'];
- TotalPrice.AsString := ANode.AttributeValueByNameUTF8['合价'];
- IsLeaf.AsBoolean := True;
- if dt = '21' then
- begin
- IsSpecialInterim.AsBoolean := True;
- InterimType.AsInteger := 3; // 显示专业工程
- end;
- CalcFlag.AsInteger := Flag_CustomTotalPrice;
- EndUpdate;
- end;
- end;
- var i: Integer;
- vItem: TScBillsItem;
- begin
- if not Assigned(ANode) then Exit;
- if (Utf8ToAnsi(ANode.Name) <> '工程量清单明细') then Exit;
- vItem := AddItemMX(AProject, AParentItem, ANode);
- if Assigned(ANode.Elements[0]) then
- RcsvAddBillItems(AProject, vItem, ANode.Elements[0]);
- if Assigned(ANode.NextSib) then
- RcsvAddBillItems(AProject, AParentItem, ANode.NextSib);
- end;
- procedure TXMLPort.RcsvAddDayWorks(AProject: TObject;
- AParentItem: TScBillsItem; ANode: TXmlNode);
- function AddDayWrokMX(AProject: TObject; AParentItem: TScBillsItem; ANode: TXmlNode): TScBillsItem;
- begin
- Result := TScProject(AProject).Bills.BillsTree.AddBillsItem(AParentItem.ID, -1);
- with Result.Rec do
- begin
- BeginUpdate;
- Code.AsString := ANode.AttributeValueByNameUTF8['序号'];
- Name.AsString := ANode.AttributeValueByNameUTF8['名称'];
- TotalPrice.AsString := ANode.AttributeValueByNameUTF8['合价'];
- CalcFlag.AsInteger := Flag_CustomTotalPrice;
- EndUpdate;
- end;
- end;
- var i: Integer;
- vItem: TScBillsItem;
- begin
- if not Assigned(ANode) then Exit;
- if (Utf8ToAnsi(ANode.Name) <> '计日工信息标题') and (Utf8ToAnsi(ANode.Name) <> '计日工信息明细') then Exit;
- if (ANode.AttributeValueByNameUTF8['数据类型'] <> '0') then // 计日工这条重复。且招标文件这里的计日工第一层是平级,无树结构。
- begin
- vItem := AddDayWrokMX(AProject, AParentItem, ANode);
- end;
- if Assigned(ANode.Elements[0]) then
- RcsvAddDayWorks(AProject, vItem, ANode.Elements[0]);
- if Assigned(ANode.NextSib) then
- RcsvAddDayWorks(AProject, AParentItem, ANode.NextSib);
- end;
- function TXMLPort.BV(AName: string): string;
- begin
- Result := ProjectManager.GetBuildProjectProperty(FBuildProjRec, AName);
- end;
- procedure TXMLPort.SetBuildProjRec(const Value: TsdDataRecord);
- begin
- FBuildProjRec := Value;
- end;
- procedure TXMLPort.SetOnOpenProject(const Value: TNotifyEvent);
- begin
- FOnOpenProject := Value;
- end;
- procedure TXMLPort.ZipFiles(AFileList: TStringList; AResultFileName: string);
- var vZip: TVCLZip;
- i: Integer;
- begin
- vZip := TVCLZip.Create(nil);
- try
- for i := 0 to AFileList.Count - 1 do
- begin
- vZip.FilesList.Add(AFileList[i]);
- end;
- vZip.ZipName := AResultFileName;
- vZip.Recurse := True;
- vZip.OverwriteMode := Always;
- vZip.Zip;
- for i := 0 to AFileList.Count - 1 do
- begin
- SysUtils.DeleteFile(PChar(AFileList[i]));
- end;
- finally
- vZip.Free;
- end;
- end;
- { TqgXMLPort }
- procedure TqgXMLPort.AddCprjInfo;
- var sProg1, sProg2, sT: string;
- begin
- FRoot.Name := 'CprjInfo';
- FRoot.AttributeAddUTF8('CprjName', PD.BuildProjectName);
- FRoot.AttributeAddUTF8('CalculateMode', IntToStr(PD.Properties.UnitPriceMode + 1));
- sT := '';
- case TScProject(FProject).ProjType of
- ptBills: sT := 'QDYS';
- ptBudget: sT := 'SGYS';
- ptBillsBudget: sT := 'SJYS';
- ptBudgetEstimate: sT := 'SJGS';
- ptFeasibilityEstimate: sT := 'GKGS';
- ptProposalEstimate: sT := 'JYGS';
- end;
- FRoot.AttributeAddUTF8('CprjType', sT);
- FRoot.AttributeAddUTF8('SmartcostDigit', 'True');
- if Progressive then
- sProg1 := 'True'
- else
- sProg1 := 'False';
- if Progressive2 then
- sProg2 := 'True'
- else
- sProg2 := 'False';
- FRoot.AttributeAddUTF8('CSDFeeProgressive', sProg1);
- FRoot.AttributeAddUTF8('OECFeesProgressive', sProg2);
- FRoot.AttributeAddUTF8('ProgressiveFile', ProgressiveFile);
- end;
- procedure TqgXMLPort.AddDecimalOption;
- var vDO: TXmlNode;
- begin
- vDO := FRoot.NodeNewUTF8('DecimalOption');
- vDO.AttributeAddUTF8('ItemPricePrecision', IntToStr(PD.Project.DigitManager.UnitPriceDigit));
- vDO.AttributeAddUTF8('ItemSumPrecision', IntToStr(PD.Project.DigitManager.TotalPriceDigit));
- vDO.AttributeAddUTF8('NormNumPrecision', IntToStr(PD.Project.DigitManager.RationQuantityDigit));
- vDO.AttributeAddUTF8('NormPricePrecision', IntToStr(PD.Project.DigitManager.RationBuildPriceDigit));
- vDO.AttributeAddUTF8('NormSumPrecision', IntToStr(PD.Project.DigitManager.RationFeesDigit));
- vDO.AttributeAddUTF8('Consumption', IntToStr(PD.Project.DigitManager.GLJQuantityDigit));
- vDO.AttributeAddUTF8('ConsumePrice', IntToStr(PD.Project.DigitManager.BudgetPriceDigit));
- vDO.AttributeAddUTF8('RatePrecision', IntToStr(PD.Project.DigitManager.RateDigit));
- end;
- procedure TqgXMLPort.AddSystemInfo;
- begin
- AddProgressForm(10, '正在生成系统信息...');
- FSystemInfoNode := FRoot.NodeNewUTF8('SystemInfo');
- FSystemInfoNode.AttributeAddUTF8('Name', '公路工程造价数据标准');//PD.BuildProjectName;
- FSystemInfoNode.AttributeAddUTF8('Version', '1.0');
- FSystemInfoNode.AttributeAddUTF8('SoftwareName', Application.Title);
- FSystemInfoNode.AttributeAddUTF8('SoftwareVer', ScGetVersion);
- FSystemInfoNode.AttributeAddUTF8('SoftwareCompany', '珠海纵横创新软件有限公司');
- // FSystemInfoNode.AttributeAdd('MakeDate', FormatDateTime('yyyy-mm-ddThh:nn:ss', Now)); // Copy(DateToStr(PD.EditDate), 1, 10)
- FSystemInfoNode.AttributeAddUTF8('MakeDate', FormatDateTime('yyyy-mm-dd', Now) + 'T' + FormatDateTime('hh:nn:ss', Now));
- end;
- procedure TqgXMLPort.AddRationLibs;
- var vLibs: TScProjectRationLibs;
- vLib: TScProjectRationLib;
- I, l: Integer;
- function IsExist(ALibName: string): Boolean;
- var
- K: Integer;
- begin
- Result := False;
- for K := 0 to Length(FAllLibNames) - 1 do
- begin
- if FAllLibNames[K] = ALibName then
- begin
- Result := True;
- Break;
- end;
- end;
- end;
- begin
- FGDSZDEKID := -1; // 每个项目都要初始化一次,重新赋值库ID。(因为总是从 0、1、2、3...开始,没有真正的唯一性ID)
- vLibs := TScProject(FProject).RationLibs;
- SetLength(FLibArr, 0);
- SetLength(FLibArr, vLibs.Count);
- for I := 0 to vLibs.Count - 1 do
- begin
- vLib := vLibs.FindLib(I);
- FLibArr[I].Value := vLib.ID;
- FLibArr[I].Name := vLib.LibName;
- // FGDSZDEKID 正常情况下值为-1。当该属性值不为-1时,表示本项目存在该定额库,此时进一步判断,ID一致时,即为条件符合
- if (vLib.LibName = '广东省市政工程综合定额(2018)') then FGDSZDEKID := vLib.ID;
- if not IsExist(vLib.LibName) then
- begin
- FNormLibNode := FCostBasisNode.NodeNewUTF8('NormLib');
- FNormLibNode.AttributeAddUTF8('NormLibNo', GetMapValue(GetMap('Map_RationLib'), vLib.LibName));
- FNormLibNode.AttributeAddUTF8('NormLibName', vLib.LibName);
- if (Length(FAllLibNames) = 0) then // 如果是主定额库,则显示“ZDEK”;如果是借用定额库,则显示“JYDEK”。
- FNormLibNode.AttributeAddUTF8('Type', 'ZDEK')
- else
- FNormLibNode.AttributeAddUTF8('Type', 'JYDEK');
- l := Length(FAllLibNames) + 1;
- SetLength(FAllLibNames, l);
- FAllLibNames[l-1]:= vLib.LibName;
- end;
- end;
- end;
- procedure TqgXMLPort.AddCostBasis;
- begin
- AddProgressForm(10, '正在生成造价依据信息...');
- FCostBasisNode := FRoot.NodeNewUTF8('CostBasis');
- case TScProject(FProject).ProjType of
- ptBills, ptBudget, ptBudgetEstimate:
- begin
- FCostBasisNode.AttributeAddUTF8('MakeRuleNo', 'GYSBB-000000-2018-86');
- FCostBasisNode.AttributeAddUTF8('MakeRuleName', '公路工程建设项目概算预算编制办法');
- FCostBasisNode.AttributeAddUTF8('ItemStandardNo', 'GYSFX-000000-2018-86');
- end;
- ptFeasibilityEstimate, ptProposalEstimate:
- begin
- FCostBasisNode.AttributeAddUTF8('MakeRuleNo', 'GSBB-000000-2018-86');
- FCostBasisNode.AttributeAddUTF8('MakeRuleName', '公路工程建设项目投资估算编制办法');
- FCostBasisNode.AttributeAddUTF8('ItemStandardNo', 'GSFX-000000-2018-86');
- end;
- end;
- end;
- procedure TqgXMLPort.AddRate(AFileNo: Integer);
- var sSQL, sSQLTemp, sTemp: string;
- function GetRateLibNo: string;
- var sName: string;
- begin
- FSearch1.Close;
- FSearch1.SQL.Text := 'select Caption From FeeParams where ID=2';
- FSearch1.Open;
- sName := FSearch1.FieldByName('Caption').asString;
- FSearch1.Close;
- Result := GetMapValue(GetMap('Map_FeeRateLib'), sName);
- end;
- begin
- AddProgressForm(10, '正在生成费率文件信息...');
- FRateNode := FRoot.NodeNewUTF8('Rate');
- FRateNode.AttributeAddUTF8('RateNo', IntToStr(AFileNo));
- FRateNode.AttributeAddUTF8('Name', ExtractFileName(FFeeRateFile.LibName));
- FRateNode.AttributeAddUTF8('RateLibNo', GetRateLibNo);
- if FFileType = xftTB then
- // sSQLTemp := 'round(Param * 1, 3) as RateParamNo, '
- sSQLTemp := 'Caption as RateParamNo, ' // 改成映射Caption列
- else
- sSQLTemp := '''0'' as RateParamNo, ';
- sSQL :=
- 'Select Switch(ID=101, ''DJSGZJFFL'', ID=102, ''YUJSGZJFFL'', ID=103, ''YEJSGZJFFL'', ID=104, ''GYDQSGZJFFL'', ' +
- 'ID=105, ''FSDQSGZJFFL'', ID=106, ''YHDQSGZJFFL'', ID=107, ''XCGRGCSGZJFFL'', ID=110, ''SGFZFFL'', ID=111, ''GDZYFFL'', ' +
- 'true, ID) as RateTypeNo, ' + sSQLTemp +
- '''1'' as Ratio from FeeParams where ID<200 and ID>2 ' +
- 'union all ' +
- 'Select Switch(ID=201, ''YANGLBXFFL'', ID=202, ''SYBXFFL'', ID=203, ''YILBXFFL'', ID=204, ''ZFGJJFL'', ID=205, ''GSBXFL'', ' +
- 'ID=301, ''JBFYFL'', ID=302, ''ZFSYFBTFL'', ID=303, ''ZGTQLFFL'', ID=304, ''ZGQNBTFL'', ID=305, ''CWFYFL'', ' +
- 'true, ID) as RateTypeNo, ' +
- 'round(Param * 1, 3) as RateParamNo, ''1'' as Ratio from FeeParams where ID>200 and MinorID=0 ' +
- 'union all ' +
- 'Select ''LRL'' as RateTypeNo, round(Profit * 1, 3) as RateParamNo, ''1'' as Ratio from FeeOthers ' +
- 'union all ' +
- 'Select ''SL'' as RateTypeNo, round(Tax * 1, 3) as RateParamNo, ''1'' as Ratio from FeeOthers ';
- // FSearch1.SQL.Text := sSQL;
- // FSearch1.SQL.SaveToFile('C:\Users\Administrator\Desktop\T2.sql');
- AddTabToXML(FQuery2, sSQL, FRateNode, 'RateParams', 'RateParam');
- if FFileType = xftTB then
- sSQL :=
- ' Select CostTypeNo as [CostTypeNo@Map_GetFeeKind_GS@0@2], RateTypeNo, RateValue from( ' +
- ' Select Code as CostTypeNo, Name, ''DJSGZJFFL'' as RateTypeNo, round(Value101 * 1, 3) as RateValue, ''01'' as orderNo from Fees ' + // 冬季施工
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''YUJSGZJFFL'' as RateTypeNo, round(Value102 * 1, 3) as RateValue, ''02'' as orderNo from Fees ' + // 雨季施工
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''YEJSGZJFFL'' as RateTypeNo, round(Value103 * 1, 3) as RateValue, ''03'' as orderNo from Fees ' + // 夜间施工
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''GYDQSGZJFFL'' as RateTypeNo, round(Value104 * 1, 3) as RateValue, ''04'' as orderNo from Fees ' + // 高原施工
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''FSDQSGZJFFL'' as RateTypeNo, round(Value105 * 1, 3) as RateValue, ''05'' as orderNo from Fees ' + // 风沙施工
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''YHDQSGZJFFL'' as RateTypeNo, round(Value106 * 1, 3) as RateValue, ''06'' as orderNo from Fees ' + // 沿海地区
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''XCGRGCSGZJFFL'' as RateTypeNo, round(Value107 * 1, 3) as RateValue, ''07'' as orderNo from Fees ' + // 行车干扰
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''SGFZFFL'' as RateTypeNo, round(Value110 * 1, 3) as RateValue, ''08'' as orderNo from Fees ' + // 施工辅助
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''GDZYFFL'' as RateTypeNo, round(Value111 * 1, 3) as RateValue, ''09'' as orderNo from Fees ' + // 工地转移(km)
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''YANGLBXFFL'' as RateTypeNo, round(Value201 * 1, 3) as RateValue, ''10'' as orderNo from Fees ' + // 养老保险(%)
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''SYBXFFL'' as RateTypeNo, round(Value202 * 1, 3) as RateValue, ''11'' as orderNo from Fees ' + // 失业保险(%)
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''YILBXFFL'' as RateTypeNo, round(Value203 * 1, 3) as RateValue, ''12'' as orderNo from Fees ' + // 医疗保险(%)
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''ZFGJJFL'' as RateTypeNo, round(Value204 * 1, 3) as RateValue, ''13'' as orderNo from Fees ' + // 住房公积金(%)
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''GSBXFL'' as RateTypeNo, round(Value205 * 1, 3) as RateValue, ''14'' as orderNo from Fees ' + // 工伤保险(%)
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''JBFYFL'' as RateTypeNo, round(Value301 * 1, 3) as RateValue, ''15'' as orderNo from Fees ' + // 基本费用
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''ZFSYFBTFL'' as RateTypeNo, round(Value302 * 1, 3) as RateValue, ''16'' as orderNo from Fees ' + // 综合里程(km)
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''ZGTQLFFL'' as RateTypeNo, round(Value303 * 1, 3) as RateValue, ''17'' as orderNo from Fees ' + // 职工探亲
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''ZGQNBTFL'' as RateTypeNo, round(Value304 * 1, 3) as RateValue, ''18'' as orderNo from Fees ' + // 职工取暖
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''CWFYFL'' as RateTypeNo, round(Value305 * 1, 3) as RateValue, ''19'' as orderNo from Fees ' + // 财务费用
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''LRL'' as RateTypeNo, round(Profit * 1, 3) as RateValue, ''20'' as orderNo from Fees, FeeOthers ' + // 利润
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''SL'' as RateTypeNo, round(Tax * 1, 3) as RateValue, ''21'' as orderNo from Fees, FeeOthers ' + // 税金
- ' ) ' +
- ' order by orderNo, CostTypeNo'
- else
- sSQL :=
- ' Select CostTypeNo as [CostTypeNo@Map_GetFeeKind_GS@0@2], RateTypeNo, RateValue from( ' +
- ' Select Code as CostTypeNo, Name, ''DJSGZJFFL'' as RateTypeNo, 0 as RateValue, ''01'' as orderNo from Fees ' + // 冬季施工
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''YUJSGZJFFL'' as RateTypeNo, 0 as RateValue, ''02'' as orderNo from Fees ' + // 雨季施工
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''YEJSGZJFFL'' as RateTypeNo, 0 as RateValue, ''03'' as orderNo from Fees ' + // 夜间施工
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''GYDQSGZJFFL'' as RateTypeNo, 0 as RateValue, ''04'' as orderNo from Fees ' + // 高原施工
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''FSDQSGZJFFL'' as RateTypeNo, 0 as RateValue, ''05'' as orderNo from Fees ' + // 风沙施工
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''YHDQSGZJFFL'' as RateTypeNo, 0 as RateValue, ''06'' as orderNo from Fees ' + // 沿海地区
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''XCGRGCSGZJFFL'' as RateTypeNo, 0 as RateValue, ''07'' as orderNo from Fees ' + // 行车干扰
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''SGFZFFL'' as RateTypeNo, 0 as RateValue, ''08'' as orderNo from Fees ' + // 施工辅助
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''GDZYFFL'' as RateTypeNo, 0 as RateValue, ''09'' as orderNo from Fees ' + // 工地转移(km)
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''YANGLBXFFL'' as RateTypeNo, 0 as RateValue, ''10'' as orderNo from Fees ' + // 养老保险(%)
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''SYBXFFL'' as RateTypeNo, 0 as RateValue, ''11'' as orderNo from Fees ' + // 失业保险(%)
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''YILBXFFL'' as RateTypeNo, 0 as RateValue, ''12'' as orderNo from Fees ' + // 医疗保险(%)
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''ZFGJJFL'' as RateTypeNo, 0 as RateValue, ''13'' as orderNo from Fees ' + // 住房公积金(%)
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''GSBXFL'' as RateTypeNo, 0 as RateValue, ''14'' as orderNo from Fees ' + // 工伤保险(%)
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''JBFYFL'' as RateTypeNo, 0 as RateValue, ''15'' as orderNo from Fees ' + // 基本费用
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''ZFSYFBTFL'' as RateTypeNo, 0 as RateValue, ''16'' as orderNo from Fees ' + // 综合里程(km)
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''ZGTQLFFL'' as RateTypeNo, 0 as RateValue, ''17'' as orderNo from Fees ' + // 职工探亲
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''ZGQNBTFL'' as RateTypeNo, 0 as RateValue, ''18'' as orderNo from Fees ' + // 职工取暖
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''CWFYFL'' as RateTypeNo, 0 as RateValue, ''19'' as orderNo from Fees ' + // 财务费用
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''LRL'' as RateTypeNo, 0 as RateValue, ''20'' as orderNo from Fees, FeeOthers ' + // 利润
- ' union all ' +
- ' Select Code as CostTypeNo, Name, ''SL'' as RateTypeNo, 0 as RateValue, ''21'' as orderNo from Fees, FeeOthers ' + // 税金
- ' ) ' +
- ' order by orderNo, CostTypeNo';
- AddTabToXML(FQuery2, sSQL, FRateNode, 'RateValues', 'RateValue', 'Flag_LrSj');
- end;
- procedure TqgXMLPort.AddPract(AFileNo: Integer);
- function GetCarTaxLibNo: string;
- var sName: string;
- begin
- FSearch1.Close;
- FSearch1.SQL.Text := Format('Select ItemValue From ProjProperty Where Name = ''%s''', ['SHORTFEETAXFILE']);
- FSearch1.Open;
- sName := FSearch1.FieldByName('ItemValue').asString;
- FSearch1.Close;
- Result := GetMapValue(GetMap('Map_CarTaxLib'), sName);
- end;
- var sAltitudeRatio: string;
- begin
- AddProgressForm(10, '正在生成工料机单价文件信息...');
- FPract := FRoot.NodeNewUTF8('Pract');
- FPract.AttributeAddUTF8('PractNo', IntToStr(AFileNo));
- FPract.AttributeAddUTF8('Name', ExtractFileName(FUnitPriceFile.LibName));
- // 费率界面的基价系数。PingCode #GLY-5678
- sAltitudeRatio := FloatToStr(TScProject(FProject).FeeRate.RationPriceRatio);
- FPract.AttributeAddUTF8('AltitudeRatio', sAltitudeRatio);
- FPract.AttributeAddUTF8('TaxLibNo', GetCarTaxLibNo); // 车船税费库编号
- FPract.AttributeAddUTF8('PriceFileNo', 'JGXX-440000-2019-05'); // 价格信息编号
- AddMps; // 人
- AddMaterials; // 材
- AddMechs; // 机
- end;
- procedure TqgXMLPort.AddEprjInfo(AFileNo: Integer);
- begin
- AddProgressForm(10, '正在生成工程项目信息...');
- FEprjInfoNode := FRoot.NodeNewUTF8('EprjInfo');
- FEprjInfoNode.AttributeAddUTF8('Name', ProjectManager.TenderName(PD.ID));
- FEprjInfoNode.AttributeAddUTF8('Sums', GetProjectTotalPrice);
- AddMakeInfo;
- AddParams(AFileNo);
- AddItems;
- end;
- procedure TqgXMLPort.AddIndexs;
- var sFile: string;
- vNode: TXmlNode;
- n: Integer;
- isNewOpen: Boolean;
- begin
- AddProgressForm(10, '正在生成指标...');
- // 打开最后一个项目
- Project := GetProjectByTenderRec(FTenderRecList[FTenderRecList.Count - 1], isNewOpen);
- FIndexsNode := FRoot.NodeNewUTF8('Indexs');
- FQuery2.Close;
- FQuery2.SQL.Clear;
- FQuery2.SQL.Add(Format('SELECT Caption FROM FeeParams WHERE ID = %d', [1]));
- FQuery2.Open;
- if FQuery2.RecordCount > 0 then
- begin
- FQuery2.First;
- vNode := FIndexsNode.NodeNewUTF8('IndexItem');
- vNode.AttributeAddUTF8('Code', 'JBSX1');
- vNode.AttributeAddUTF8('Name', '工程所在地');
- vNode.AttributeAddUTF8('Unit', '');
- vNode.AttributeAddUTF8('Value', FQuery2.FieldByName('Caption').asString);
- vNode.AttributeAddUTF8('Remark', '');
- end;
- FQuery2.Close;
- if isNewOpen then
- TScProjBaseData(TScProject(Project).ProjData).Close;
- end;
- // [2.2.1 & 2.3.1]、导出材料计算用的定额。AType: 1原价,0运费(和数据库 MaterialRations 表 Type 字段保持一致) // 类型(0,运费;1,原价)
- procedure TqgXMLPort.AddMCRations(AParentNode: TXmlNode; AType, AMaterialID, ABillID: Integer);
- var sSQL, sFN, sKey, sCode: string;
- vVirParent, vNorm, vCS, vCItem, vConsume, vConsumeItem: TXmlNode;
- iRationID, i, iMaxFeeCode, iID, iType, iCalcType: Integer;
- begin
- sSQL := Format('Select * from MaterialRations where OwnerID=%d and BillsID=%d and Type=%d', [AMaterialID, ABillID, AType]);
- FQuery4.Close;
- FQuery4.SQL.Text := sSQL;
- FQuery4.Open;
- if FQuery4.RecordCount > 0 then
- begin
- // 添加虚拟父层,我们软件没有这层
- if AType = 1 then
- begin
- vVirParent := AParentNode.NodeNewUTF8('SelfCollect');
- vVirParent.AttributeAddUTF8('OtherCost', '0');
- end
- else
- begin
- vVirParent := AParentNode.NodeNewUTF8('SelfTrans');
- end;
- iMaxFeeCode := TScProject(FProject).FeeRate.MaxFeeCode;
- FQuery4.First;
- while not FQuery4.Eof do
- begin
- iRationID := FQuery4.FieldByName('ID').AsInteger;
- vNorm := vVirParent.NodeNewUTF8('Norm');
- vNorm.AttributeAddUTF8('NormLibNo', GetNormLibNoByID(FQuery4.FieldByName('LibID').AsInteger));
- vNorm.AttributeAddUTF8('DisplayCode', FQuery4.FieldByName('Code').asString);
- vNorm.AttributeAddUTF8('Name', FQuery4.FieldByName('Name').asString);
- vNorm.AttributeAddUTF8('Unit', ChangeUnit_m3(FQuery4.FieldByName('Unit').asString));
- vNorm.AttributeAddUTF8('Num', FQuery4.FieldByName('Quantity').asString);
- if (FQuery4.FieldByName('GYFeeKind').AsInteger > iMaxFeeCode) then
- vNorm.AttributeAddUTF8('CostTypeNo', 'BJ') // 兼容旧项目的旧取费类别。如果当前取费类别编号大于费率文件中的定义,则识别为不计。
- else
- vNorm.AttributeAddUTF8('CostTypeNo', GetMapValue(GetMap('Map_GetFeeKind_GS'), FQuery4.FieldByName('GYFeeKind').asString, 0, 2));
- vNorm.AttributeAddUTF8('FabricationCost', FQuery4.FieldByName('BuildingFee').asString);
- vNorm.AttributeAddUTF8('AdjustStatus', FQuery4.FieldByName('AdjustState').asString);
- // 定额的费用组成:人工费、材料费...
- vCS := vNorm.NodeNewUTF8('CostStructure');
- for i := Low(Map_RationFees) to High(Map_RationFees) do
- begin
- if FQuery4.FindField(Map_RationFees[i][0]) <> nil then
- begin
- vCItem := vCS.NodeNewUTF8('CostItem');
- vCItem.AttributeAddUTF8('ItemNo', Map_RationFees[i][1]);
- if FFileType = xftTB then
- vCItem.AttributeAddUTF8('Sum', CheckNull(FQuery4.FieldByName(Map_RationFees[i][0]).asString))
- else
- vCItem.AttributeAddUTF8('Sum', '0');
- end;
- end;
- // 导出材料计算的定额的工料机
- sSQL := Format(
- 'SELECT P.Code, P.type, P.CalculateType, M.Quantity as Consumption, M.GLJID as ID ' +
- 'FROM MaterialGLJList as M Left join Port_Prj as P on M.GLJID=P.GLJID ' +
- 'WHERE M.OwnerID=%d and M.BillsID=%d and M.RationID=%d and M.Type <> 9',
- [AMaterialID, ABillID, iRationID]);
- FQuery5.Close;
- FQuery5.SQL.Text := sSQL;
- FQuery5.Open;
- vConsume := vNorm.NodeNewUTF8('Consume');
- FQuery5.First;
- while not FQuery5.Eof do
- begin
- vConsumeItem := vConsume.NodeNewUTF8('ConsumeItem');
- for i := 0 to FQuery5.FieldCount - 1 do
- begin
- sFN := FQuery5.Fields[i].FieldName;
- if (sFN = 'ID') or (sFN = 'type') or (sFN = 'CalculateType') then Continue;
- // 效果示例:vNode.AttributeAdd('Code'] := FQuery2.FieldByName('Code').AsString;
- vConsumeItem.AttributeAddUTF8(sFN, FQuery5.Fields[i].AsString);
- end;
- FQuery5.Next;
- end;
- FQuery4.Next;
- end;
- end;
- FQuery4.Close;
- end;
- procedure TqgXMLPort.AddElectric(AMaterialNode: TXmlNode);
- var sSQL: string;
- vElecNode: TXmlNode;
- begin
- sSQL := 'Select * From ElectricityCalc';
- FQuery3.Close;
- FQuery3.SQL.Text := sSQL;
- FQuery3.Open;
- if FQuery3.RecordCount > 0 then
- begin
- FQuery3.First;
- while not FQuery3.Eof do
- begin
- vElecNode := AMaterialNode.NodeNewUTF8('Electro');
- vElecNode.AttributeAddUTF8('Code', FQuery3.FieldByName('Code').AsString);
- vElecNode.AttributeAddUTF8('Price', FQuery3.FieldByName('Price').AsString);
- vElecNode.AttributeAddUTF8('Ratio', FQuery3.FieldByName('SumRate').AsString);
- FQuery3.Next;
- end;
- end;
- FQuery3.Close;
- end;
- // [2.2]、导出材料原价
- procedure TqgXMLPort.AddOrgPrices(AMaterialNode: TXmlNode; AMaterialID: Integer);
- var sSQL: string;
- vOrgPrices: TXmlNode;
- iBillID: Integer;
- begin
- // 原价清单
- sSQL := 'Select Price, SumRate, Location, ID from MaterialOrgPrice where OwnerID = ' + IntToStr(AMaterialID);
- FQuery3.Close;
- FQuery3.SQL.Text := sSQL;
- FQuery3.Open;
- if FQuery3.RecordCount > 0 then
- begin
- FQuery3.First;
- while not FQuery3.Eof do
- begin
- vOrgPrices := AMaterialNode.NodeNewUTF8('OrgPrices');
- vOrgPrices.AttributeAddUTF8('OrgPricevalue', FQuery3.FieldByName('Price').AsString);
- vOrgPrices.AttributeAddUTF8('Ratio', FQuery3.FieldByName('SumRate').AsString);
- vOrgPrices.AttributeAddUTF8('SupplyLocation', FQuery3.FieldByName('Location').AsString);
- iBillID := FQuery3.FieldByName('ID').AsInteger;
- AddMCRations(vOrgPrices, 1, AMaterialID, iBillID);
- FQuery3.Next;
- end;
- end;
- FQuery3.Close;
- end;
- // [2.3]、导出材料运费
- procedure TqgXMLPort.AddTranFees(AMaterialNode: TXmlNode; AMaterialID: Integer);
- var sSQL: string;
- vTransFees: TXmlNode;
- iBillID: Integer;
- begin
- // 运杂清单(起讫地点)
- sSQL :=
- 'Select Locations,Length,UnitPrice,ZXCount,ZXPrice,OtherPrice,SumRate,Price,T.ID,C.Name ' +
- 'from MaterialTransPrice as T left join MaterialConveyance as C on T.Conveyance = C.ID where OwnerID = ' + IntToStr(AMaterialID);
- FQuery3.Close;
- FQuery3.SQL.Text := sSQL;
- FQuery3.Open;
- if FQuery3.RecordCount > 0 then
- begin
- FQuery3.First;
- while not FQuery3.Eof do
- begin
- vTransFees := AMaterialNode.NodeNewUTF8('TransFees');
- vTransFees.AttributeAddUTF8('FromPlace', FQuery3.FieldByName('Locations').AsString);
- vTransFees.AttributeAddUTF8('TransWay', FQuery3.FieldByName('Name').AsString);
- vTransFees.AttributeAddUTF8('TransDistence', FQuery3.FieldByName('Length').AsString);
- vTransFees.AttributeAddUTF8('TransFee', FQuery3.FieldByName('UnitPrice').AsString);
- vTransFees.AttributeAddUTF8('LoadTimes', FQuery3.FieldByName('ZXCount').AsString);
- vTransFees.AttributeAddUTF8('LoadCost', FQuery3.FieldByName('ZXPrice').AsString);
- vTransFees.AttributeAddUTF8('OtherCost', FQuery3.FieldByName('OtherPrice').AsString);
- vTransFees.AttributeAddUTF8('Ratio', FQuery3.FieldByName('SumRate').AsString);
- vTransFees.AttributeAddUTF8('Freight', FQuery3.FieldByName('Price').AsString);
- iBillID := FQuery3.FieldByName('ID').AsInteger;
- AddMCRations(vTransFees, 0, AMaterialID, iBillID);
- FQuery3.Next;
- end;
- end;
- FQuery3.Close;
- end;
- // [1]、导出【人工】
- procedure TqgXMLPort.AddMps;
- var sSQL: string;
- begin
- FPract_Mps := FPract.NodeNewUTF8('Mps');
- if FFileType = xftTB then
- begin
- sSQL := 'Select Code, Name as PractName, Specs as Spec, Unit, ' +
- 'BudgetPrice, RationPrice as NormPrice, IIF(New=True,1,0) as IsAdd ' +
- 'from Port_Prj ' +
- 'where Type = 1';
- AddTabToXML(FQuery1, sSQL, FPract_Mps, '', 'Mp');
- end;
- end;
- // [2]、导出【材料】 2 混凝土 3 材料(兼容旧项目) 4 材料 6 设备。
- // 联合MaterialPrice表是为了查询材料的原价、运价、运杂费率等基础数据。
- // 注意:ID 要取两个,MaterialPrice 的 ID 用来判断当前材料是否有材料计算信息,ID为空表示没有。
- procedure TqgXMLPort.AddMaterials;
- var sSQL, sFN, sName: string;
- vNode, vElecNode: TXmlNode;
- i, iMtID, iType, iCalcType, n: Integer;
- begin
- FPract_Materials := FPract.NodeNewUTF8('Materials');
- if FFileType <> xftTB then Exit;
- AddProgressForm(0, '导出项目工料机(材料),校验材料类型...');
- // SHValue 场外运输损耗费 HSValue (包装)回收价值 BGValue 采购保管费
- sSQL :=
- 'Select P.GLJID as P_GLJID, P.Type as Type, P.CalculateType as CalculateType, P.Code, P.Name as PractName, P.Specs as Spec, P.Unit,' +
- 'BudgetPrice, RationPrice as NormPrice, Amount as Num, DutiablePrice as TaxInPrice, TaxFeeRate as TaxRate, ' +
- 'IIF(New=True,1,0) as IsAdd, ' +
- 'IIF(M.OrgPrice is null, 0, M.OrgPrice) as OrgPrice, IIF(TransPrice is null, 0, TransPrice) as TransFee, ' +
- 'IIF(MZRate is null, 0, MZRate) as GwRate, IIF(M.SHRate is null, 0, M.SHRate) as OffSiteLf, 0 as OnSiteLf, ' +
- 'IIF(ZXRate is null, 0, ZXRate) as LoadLf, IIF(BGRate is null, 0, BGRate) as StoreRate, ' +
- 'IIF(HSValue is null, 0, HSValue) as PackageRecycleFee, ' +
- 'ProvidePlace as SupplyLocation, ZXCount as HandlingTimes, ' +
- 'M.ID as MID ' +
- 'From Port_Prj as P Left join MaterialPrice as M on P.GLJID = M.ID where P.Type in (2,3,4,6) ' +
- 'Order by P.Code, P.GLJID';
- FQuery2.Close;
- FQuery2.SQL.Text := sSQL;
- FQuery2.Open;
- if FQuery2.RecordCount = 0 then Exit;
- n := 0;
- FQuery2.First;
- while not FQuery2.Eof do
- begin
- Inc(n);
- AddProgressForm(1, Format('导出项目工料机,校验材料类型 [%d/%d]...', [n, FQuery2.RecordCount]));
- vNode := FPract_Materials.NodeNewUTF8('Material');
- for i := 0 to FQuery2.FieldCount - 1 do
- begin
- sFN := FQuery2.Fields[i].FieldName;
- if (sFN = 'MID') or (sFN = 'P_GLJID') or (sFN = 'CalculateType') then Continue;
- if (sFN = 'Code') then
- begin
- vNode.AttributeAddUTF8('Code', FQuery2.FieldByName('Code').AsString);
- // 电。综合电价计算
- if (FQuery2.FieldByName('Code').AsString = '3005002') then
- begin
- AddElectric(vNode);
- end;
- end
- else if (sFN = 'Type') then
- begin
- iType := FQuery2.FieldByName('Type').AsInteger;
- iCalcType := FQuery2.FieldByName('CalculateType').AsInteger;
- sName := FQuery2.FieldByName('PractName').AsString;
- vNode.AttributeAddUTF8('Type', IntToStr(GetType(iType, iCalcType, sName)));
- end
- else
- // 效果示例:vNode.AttributeAddUtf8('Code', FQuery2.FieldByName('Code').AsString);
- vNode.AttributeAddUTF8(sFN, FQuery2.Fields[i].AsString);
- end;
- iMtID := FQuery2.FieldByName('MID').AsInteger;
- if iMtID > 0 then // 证明存在材料计算:原价计算或运杂费计算
- begin
- if FQuery2.FieldByName('OrgPrice').AsCurrency > 0 then // 原价
- AddOrgPrices(vNode, iMtID);
- if FQuery2.FieldByName('TransFee').AsCurrency > 0 then // 运杂
- AddTranFees(vNode, iMtID);
- end;
- FQuery2.Next;
- end;
- FQuery2.Close;
- end;
- // [3]、导出【机械】
- procedure TqgXMLPort.AddMechs;
- var sSQL, sCode, sValue: string;
- vNode, vFixedCost, vVariableCost, vFixedCostItem, vVariableCostItem: TXmlNode;
- i: Integer;
- begin
- FPract_Mechs := FPract.NodeNewUTF8('Mechs');
- if FFileType <> xftTB then Exit;
- AddProgressForm(0, '导出项目工料机(机械)...');
- sSQL :=
- 'Select P.GLJID as P_GLJID, P.Code as PCode, P.Name as PName, P.Specs as PSpecs, P.Unit as PUnit, P.Amount as PAmount, P.type as P_Type, ' +
- 'P.CalculateType as P_CalculateType, P.RationPrice as PRPrice, P.BudgetPrice as PBudgetPrice, P.RationPrice as PRationPrice, P.New as PNew, M.* ' +
- 'from Port_Prj as P Left join MachinePrice as M on P.GLJID = M.ID where P.Type = 8 ';
- FQuery2.Close;
- FQuery2.SQL.Text := sSQL;
- FQuery2.Open;
- if FQuery2.RecordCount = 0 then Exit;
- FQuery2.First;
- while not FQuery2.Eof do
- begin
- vNode := FPract_Mechs.NodeNewUTF8('Mech');
- sCode := FQuery2.FieldByName('PCode').AsString;
- vNode.AttributeAddUTF8('Code', sCode);
- vNode.AttributeAddUTF8('PractName', FQuery2.FieldByName('PName').AsString);
- vNode.AttributeAddUTF8('Spec', FQuery2.FieldByName('PSpecs').AsString);
- vNode.AttributeAddUTF8('Unit', ChangeUnit_m3(FQuery2.FieldByName('PUnit').AsString));
- vNode.AttributeAddUTF8('BudgetPrice', FQuery2.FieldByName('PBudgetPrice').AsString);
- vNode.AttributeAddUTF8('NormPrice', FQuery2.FieldByName('PRationPrice').AsString);
- vNode.AttributeAddUTF8('Num', FQuery2.FieldByName('PAmount').AsString);
- vNode.AttributeAddUTF8('IsAdd', CheckBool(FQuery2.FieldByName('PNew').AsString));
- if (sCode <> SSmallMachineFeeCode) then // 小型机具使用费不要导出组成物
- begin
- vFixedCost := vNode.NodeNewUTF8('FixedCost');
- sValue := CheckNull(FQuery2.FieldByName('BBFee').AsString);
- vFixedCost.AttributeAddUTF8('FixedCostSum', sValue);
- vFixedCost.AttributeAddUTF8('FixedRate', FloatToStr(PD.MachineBBFeeRate));
- if (StrToFloat(sValue) > 0) then
- begin
- for i := Low(Map_Machine_BBFee) to High(Map_Machine_BBFee) do
- begin
- vFixedCostItem := vFixedCost.NodeNewUTF8('FixedCostItem');
- vFixedCostItem.AttributeAddUTF8('FixedCostNo', Map_Machine_BBFee[i][1]);
- vFixedCostItem.AttributeAddUTF8('Sum', FQuery2.FieldByName(Map_Machine_BBFee[i][0]).AsString);
- end;
- end;
- vVariableCost := vNode.NodeNewUTF8('VariableCost');
- sValue := CheckNull(FQuery2.FieldByName('KBFee').AsString);
- vVariableCost.AttributeAddUTF8('VariableCostSum', sValue);
- if (StrToFloat(sValue) > 0) then
- begin
- for i := Low(Map_Machine_KBFee) to High(Map_Machine_KBFee) do
- begin
- vVariableCostItem := vVariableCost.NodeNewUTF8('VariableCostItem');
- vVariableCostItem.AttributeAddUTF8('VariableCostNo', Map_Machine_KBFee[i][1]);
- vVariableCostItem.AttributeAddUTF8('Consumption', FQuery2.FieldByName(Map_Machine_KBFee[i][0]).AsString);
- end;
- end;
- end;
- FQuery2.Next;
- end;
- FQuery2.Close;
- end;
- // 清单-公式
- procedure TqgXMLPort.AddFormula(ANode: TScBillsItem; AParentXMLNode: TXmlNode);
- // 判断清单是否存在
- function IsBillExist(AID: Integer): Boolean;
- begin
- Result := False;
-
- if (AID >= 500) and (AID <= 999) then // 虚拟清单
- begin
- Result := True;
- Exit;
- end;
- FSearch1.Close;
- FSearch1.SQL.Text := 'select ID from Bills where ID=' + IntToStr(AID);
- FSearch1.Open;
- if FSearch1.RecordCount > 0 then
- Result := True;
- FSearch1.Close;
- end;
- // =100+200+@1+@502+@1102+@504*9%
- // 最终只能使用三方正则库。目前以下算法不能解决:①部分匹配。如 @1,@1101 ②行引用表达式。如 @1102*9%。
- // 云版要求:"{DEJAFⅡ}+{ZXZDHJ}+{GZQDHJ}+{@1101}+{@4}"
- function getFormulas(ABillID: Integer): string;
- var
- sExpr, sOld, sNew, sMapName: string;
- reg: TPerlRegEx;
- iID: Integer;
- vItem: TScBillsItem;
- begin
- sExpr := '';
- sExpr := TScProject(FProject).Exprs.GetExprs(ExprsID_Bills, ExprsID_Bills_TotalPrice, ABillID, 0);
- if (sExpr = '') and IsSpecialFormulaBill(ABillID) then
- begin
- case ABillID of
- idSpecialInterimSum: Result := '{ZXZDHJ}'; // 专项暂定合计
- idBillSumExcludeSpecialInterim: Result := '{GZQDHJ}-{ZXZDHJ}'; // 各章清单合计 - 专项暂定合计
- idProjectTotalPrice_Bills:
- begin
- vItem := BillNode(39); // 清单类型的项目,其它新增费用
- if vItem <> nil then
- Result := '{D100Z700}+{JRG}+{ZLJE}+{QTXZFY}' // 第一部分合计 + 计日工 + 不可预见费(暂列金额)+ 其它新增费用
- else
- Result := '{D100Z700}+{JRG}+{ZLJE}';
- end;
- end;
- Exit;
- end;
- if Pos('=', sExpr) = 0 then // 没有"=",是纯四则运算表达式,如:1924*48+20.73*20400
- begin
- Result := sExpr;
- Exit;
- end;
- sExpr := StringReplace(sExpr, '=', '', []);
- reg := TPerlRegEx.Create;
- try
- reg.Subject := sExpr;
- reg.RegEx := '@\d+';
- while reg.MatchAgain do
- begin
- sOld := reg.MatchedText;
- // 检验@xx 是否存在
- iID := StrToInt(Copy(sOld, 2, Length(sOld) - 1));
- if IsBillExist(iID) then
- begin
- if TScProject(FProject).IsBills then
- sMapName := 'Map_Formula_Bill'
- else
- sMapName := 'Map_Formula_Budget';
- sNew := GetMapValue(GetMap(sMapName), sOld, 0, 2);
- end
- else
- sNew := '0';
- if sNew <> '' then
- begin
- reg.Replacement := sNew;
- reg.Replace; // 不能使用 reg.ReplaceAll; 只能使用 reg.Replace; 逐个匹配。
- end
- else // 为空表示标准映射列表中没有,是行引用
- begin
- reg.Replacement := '{' + sOld + '}';
- reg.Replace;
- end;
- end;
- Result := reg.Subject;
- finally
- reg.Free;
- end;
- end;
- var vFormulaNode: TXmlNode;
- begin
- vFormulaNode := AParentXMLNode.NodeNewUTF8('Formula');
- vFormulaNode.AttributeAddUTF8('Name', Rec(ANode, 'Name'));
- vFormulaNode.AttributeAddUTF8('Formulas', getFormulas(ANode.ID));
- vFormulaNode.AttributeAddUTF8('Ratio', '1');
- vFormulaNode.AttributeAddUTF8('Sum', Rec(ANode, 'TotalPrice'));
- vFormulaNode.AttributeAddUTF8('Remarks', Rec(ANode, 'MemoStr'));
- end;
- // 清单-定额、量价、设备
- procedure TqgXMLPort.AddRations(ANode: TScBillsItem; AParentXMLNode: TXmlNode);
- var vNorm, vCS, vCItem, vCost, vConsume, vConsumeItem: TXmlNode;
- i, iMaxFeeCode, iID, iType, iCalcType: Integer;
- sTemp, sSQL, sFN, sME, sStatus, sExpr, sKey, sCode, sUnit, sSpec, sGLJID: string;
- vRation: TScRationRecord;
- begin
- iMaxFeeCode := TScProject(FProject).FeeRate.MaxFeeCode;
- FQuery2.Close;
- FQuery2.SQL.Clear;
- FQuery2.SQL.Add(Format('SELECT * FROM RationCalcList WHERE BillsItemID = %d Order by SerialNo', [ANode.ID]));
- FQuery2.Open;
- if FQuery2.RecordCount = 0 then
- begin
- FQuery2.Close;
- Exit;
- end;
- FQuery2.First;
- while not FQuery2.Eof do
- begin
- // (1) 量价、设备
- if FQuery2.FieldByName('Type').AsInteger = 1 then
- begin
- vCost := AParentXMLNode.NodeNewUTF8('Cost');
- // 编号不能直接取。因为有可能被重新编号过的。要从Port_Prj中取最新的。
- // vCost.AttributeAddUtf8('Code', FQuery2.FieldByName('Code').AsString);
- FQuery3.Close;
- FQuery3.SQL.Text := Format('SELECT Code FROM Port_Prj WHERE GLJID = %d', [
- FQuery2.FieldByName('GLJID').AsInteger]);
- FQuery3.Open;
- vCost.AttributeAddUTF8('Code', FQuery3.FieldByName('Code').AsString);
- FQuery3.Close;
- vCost.AttributeAddUTF8('Name', FQuery2.FieldByName('Name').AsString);
- // 直接插入工料机当定额用,旧版本有Bug,规格没有跟过来,导致这里取不到规格。此时应再去项目工料机里查。
- sSpec := FQuery2.FieldByName('Specs').AsString;
- sGLJID := FQuery2.FieldByName('GLJID').AsString;
- if (sSpec = '') and (sGLJID <> '') then // 直接插入的工料机,GLJID字段有值(其它没有)
- begin
- sSQL := Format('select Specs from Port_Prj where GLJID = %s', [sGLJID]);
- sSpec := DoSearch(sSQL, 'Specs', '');
- end;
- vCost.AttributeAddUTF8('Spec', sSpec);
- sUnit := FQuery2.FieldByName('Unit').asString;
- sUnit := ChangeUnit_m3(sUnit);
- vCost.AttributeAddUTF8('Unit', sUnit);
- vCost.AttributeAddUTF8('Num', FQuery2.FieldByName('Quantity').asString);
- sExpr := '';
- sExpr := TScProject(FProject).Exprs.GetExprs(ExprsID_CountPrice, ExprsID_CountPrice_Quantity, FQuery2.FieldByName('ID').AsInteger, 0);
- vCost.AttributeAddUTF8('NumExpression', sExpr);
- sME := CheckBool(FQuery2.FieldByName('IsMECalc').asString);
- if (sME = '1') then
- vCost.AttributeAddUTF8('BasePrice', FQuery2.FieldByName('UnitPrice').asString) // 设备的基价取 UnitPrice
- else
- vCost.AttributeAddUTF8('BasePrice', FQuery2.FieldByName('RationUnitDirectFee').asString); // 量价的基价取 RationUnitDirectFee
- vCost.AttributeAddUTF8('Price', FQuery2.FieldByName('UnitDirectFee').asString);
- vCost.AttributeAddUTF8('IsEquipment', sME);
- if (sME = '1') then
- begin
- vCost.AttributeAddUTF8('TransMiscRate', FQuery2.FieldByName('YZFeeRate').asString);
- vCost.AttributeAddUTF8('TransInsuRate', FQuery2.FieldByName('YBFeeRate').asString);
- vCost.AttributeAddUTF8('ProcuStorRate', FQuery2.FieldByName('CBFeeRate').asString);
- end;
- if (FQuery2.FieldByName('GetFeeKind').AsInteger > iMaxFeeCode) then
- vCost.AttributeAddUTF8('CostTypeNo', 'BJ') // 兼容旧项目的旧取费类别。如果当前取费类别编号大于费率文件中的定义,则识别为不计。
- else
- vCost.AttributeAddUTF8('CostTypeNo', GetMapValue(GetMap('Map_GetFeeKind_GS'), FQuery2.FieldByName('GetFeeKind').asString, 0, 2));
- vCost.AttributeAddUTF8('ProfitRate', FloatToStr(ScRoundTo(PD.Project.FeeRate.Rate(frProfit) * 100, -2)));
- vCost.AttributeAddUTF8('TaxRate', FloatToStr(ScRoundTo(PD.Project.FeeRate.Rate(frTax) * 100, -3)));
- vCost.AttributeAddUTF8('MpRatio', '0');
- vCost.AttributeAddUTF8('MaterialRatio', '0');
- vCost.AttributeAddUTF8('MechRatio', '0');
- if FQuery2.FieldByName('IsCalcProfit').AsBoolean then
- vCost.AttributeAddUTF8('LR', '1')
- else
- vCost.AttributeAddUTF8('LR', '0');
- if FQuery2.FieldByName('IsCalcTax').AsBoolean then
- vCost.AttributeAddUTF8('SJ', '1')
- else
- vCost.AttributeAddUTF8('SJ', '0');
- case FQuery2.FieldByName('CountPriceType').AsInteger of
- 1: vCost.AttributeValueByNameUTF8['MpRatio'] := '100';
- 2: vCost.AttributeValueByNameUTF8['MaterialRatio'] := '100';
- 3: vCost.AttributeValueByNameUTF8['MechRatio'] := '100';
- end;
- // 量价的各费(人工费、材料费...)
- vCS := vCost.NodeNewUTF8('CostStructure');
- for i := Low(Map_RationFees) to High(Map_RationFees) do
- begin
- vCItem := vCS.NodeNewUTF8('CostItem');
- vCItem.AttributeAddUTF8('ItemNo', Map_RationFees[i][1]);
- if FFileType = xftTB then
- vCItem.AttributeAddUTF8('Sum', CheckNull(FQuery2.FieldByName(Map_RationFees[i][0]).asString))
- else
- vCItem.AttributeAddUTF8('Sum', '0');
- end;
- end
- // (2) 定额
- else
- begin
- vNorm := AParentXMLNode.NodeNewUTF8('Norm');
- vNorm.AttributeAddUTF8('NormLibNo', GetNormLibNoByID(FQuery2.FieldByName('LibID').AsInteger));
- sCode := FQuery2.FieldByName('Code').asString;
- if (FGDSZDEKID <> -1) and (FQuery2.FieldByName('LibID').AsInteger = FGDSZDEKID) then
- sCode := 'D' + sCode;
- vNorm.AttributeAddUTF8('DisplayCode', sCode);
- vNorm.AttributeAddUTF8('Name', FQuery2.FieldByName('Name').asString);
- vNorm.AttributeAddUTF8('Unit', ChangeUnit_m3(FQuery2.FieldByName('Unit').asString));
- vNorm.AttributeAddUTF8('Num', FQuery2.FieldByName('Quantity').asString);
- sExpr := '';
- sExpr := TScProject(FProject).Exprs.GetExprs(ExprsID_Rations, ExprsID_Rations_Quantity, FQuery2.FieldByName('ID').AsInteger, 0);
- vNorm.AttributeAddUTF8('NumExpression', sExpr);
- if (FQuery2.FieldByName('GetFeeKind').AsInteger > iMaxFeeCode) then
- vNorm.AttributeAddUTF8('CostTypeNo', 'BJ') // 兼容旧项目的旧取费类别。如果当前取费类别编号大于费率文件中的定义,则识别为不计。
- else
- vNorm.AttributeAddUTF8('CostTypeNo', GetMapValue(GetMap('Map_GetFeeKind_GS'), FQuery2.FieldByName('GetFeeKind').asString, 0, 2));
- vNorm.AttributeAddUTF8('ProfitRate', FloatToStr(ScRoundTo(PD.Project.FeeRate.Rate(frProfit) * 100, -2)));
- vNorm.AttributeAddUTF8('TaxRate', FloatToStr(ScRoundTo(PD.Project.FeeRate.Rate(frTax) * 100, -3)));
- vNorm.AttributeAddUTF8('FabricationCost', FQuery2.FieldByName('BuildingFee').asString);
- // vNorm.AttributeAddUtf8('AdjustStatus', FQuery2.FieldByName('AdjustState').asString);
- vRation := TScProject(FProject).Rations.FindRation(FQuery2.FieldByName('ID').AsInteger);
- sStatus := AdjustStateToPort(vRation);
- vNorm.AttributeAddUTF8('AdjustStatus', sStatus);
- // 定额是强制的,一定得算利润和税金,取消不了。量价和设备可以控制
- vNorm.AttributeAddUTF8('LR', '1');
- vNorm.AttributeAddUTF8('SJ', '1');
- // (2).1 定额的各费(人工费、材料费...)
- vCS := vNorm.NodeNewUTF8('CostStructure');
- for i := Low(Map_RationFees) to High(Map_RationFees) do
- begin
- vCItem := vCS.NodeNewUTF8('CostItem');
- vCItem.AttributeAddUTF8('ItemNo', Map_RationFees[i][1]);
- if FFileType = xftTB then
- vCItem.AttributeAddUTF8('Sum', CheckNull(FQuery2.FieldByName(Map_RationFees[i][0]).asString))
- else
- vCItem.AttributeAddUTF8('Sum', '0');
- end;
- // (2).2 定额的工料机 (注意:临时项目工料机表 CalculateType -1被改成0,这会导致定额工料机定位不上)
- sSQL := Format('Select G2.*,P.Code as Code from ( ' +
- 'SELECT G.RationID, G.GLJID as GLJID, G.Quantity as Consumption, G.Type, IIF(G.CalculateType=-1, 0, G.CalculateType) as GCType, G.RationPrice ' +
- 'FROM GLJList as G ' +
- 'WHERE G.RationID=%d and G.Type <> 9) as G2 Left join Port_Prj as P ' +
- 'on G2.GLJID=P.GLJID and G2.Type=P.Type and G2.GCType=P.CalculateType and G2.RationPrice=P.RationPrice ' +
- 'WHERE G2.RationID=%d', [FQuery2.FieldByName('ID').AsInteger, FQuery2.FieldByName('ID').AsInteger]);
- FQuery3.Close;
- FQuery3.SQL.Text := sSQL;
- FQuery3.Open;
- vConsume := vNorm.NodeNewUTF8('Consume');
- FQuery3.First;
- while not FQuery3.Eof do
- begin
- vConsumeItem := vConsume.NodeNewUTF8('ConsumeItem');
- vConsumeItem.AttributeAddUTF8('Code', FQuery3.FieldByName('Code').AsString);
- vConsumeItem.AttributeAddUTF8('Consumption', FQuery3.FieldByName('Consumption').AsString);
- FQuery3.Next;
- end;
- end;
- FQuery2.Next;
- end;
- FQuery2.Close;
- end;
- procedure TqgXMLPort.AddMakeInfo;
- begin
- AddProgressForm(5, '正在生成工程项目信息1...');
- FMakeInfoNode := FEprjInfoNode.NodeNewUTF8('MakeInfo');
- FMakeInfoNode.AttributeAddUTF8('ValuationModel', '1'); // 中山接口追加
- FMakeInfoNode.AttributeAddUTF8('Manage', PD.BuildUnit);
- FMakeInfoNode.AttributeAddUTF8('Designer', '');
- FMakeInfoNode.AttributeAddUTF8('Compile', PD.Bidder); // 内容数:编4复2审3
- FMakeInfoNode.AttributeAddUTF8('CompileApprover', PD.Author);
- FMakeInfoNode.AttributeAddUTF8('CompileCertNo', PD.AuthorCertificate);
- FMakeInfoNode.AttributeAddUTF8('CompileDate', FormatDateTime('yyyy-mm-dd', PD.EditDate) + 'T' + FormatDateTime('hh:nn:ss', PD.EditDate));
- // if FFileType = xftTB then // 单机但凡有的都导出给云版用,不用管 Altova XMLSpy 检测。
- FMakeInfoNode.AttributeAddUTF8('Review', '');
- FMakeInfoNode.AttributeAddUTF8('ReviewApprover', PD.Auditor);
- FMakeInfoNode.AttributeAddUTF8('ReviewCertNo', PD.AuditorCertificate);
- FMakeInfoNode.AttributeAddUTF8('ReviewDate', FormatDateTime('yyyy-mm-dd', PD.EditDate) + 'T' + FormatDateTime('hh:nn:ss', PD.EditDate));
- // if FFileType = xftTB then
- begin
- FMakeInfoNode.AttributeAddUTF8('Examine', PD.CheckUnit);
- FMakeInfoNode.AttributeAddUTF8('ExamineApprover', PD.Checker);
- FMakeInfoNode.AttributeAddUTF8('ExamineCertNo', '');
- // 有这个属性后,Altova XMLSpy值类型检测不过。
- FMakeInfoNode.AttributeAdd('ExamineDate', FormatDateTime('yyyy-mm-dd', PD.CheckDate) + 'T' + FormatDateTime('hh:nn:ss', PD.CheckDate));
- FMakeInfoNode.AttributeAddUTF8('CompileExplain', '');
- FMakeInfoNode.AttributeAddUTF8('ExamineExplain', '');
- FMakeInfoNode.AttributeAddUTF8('ProjectExplain', '');
- end;
- end;
- procedure TqgXMLPort.AddParams(AFileNo: Integer);
- var s, sTemp: string;
- begin
- AddProgressForm(5, '正在生成工程项目信息2...');
- FParamsNode := FEprjInfoNode.NodeNewUTF8('Params');
- FParamsNode.AttributeAddUTF8('PrjArea', PD.ProjectLocation);
- FParamsNode.AttributeAddUTF8('StartPileNo', PV('StartCode'));
- FParamsNode.AttributeAddUTF8('EndPileNo', PV('StartCode'));
- if PV('Newly') = '新建' then
- FParamsNode.AttributeAddUTF8('BuildType', '0')
- else
- FParamsNode.AttributeAddUTF8('BuildType', '1');
- if PV('Topography') = '平原' then
- FParamsNode.AttributeAddUTF8('Terrain', '0')
- else
- FParamsNode.AttributeAddUTF8('Terrain', '1');
- s := PV('RoadLevel');
- if s = '一级公路' then
- FParamsNode.AttributeAddUTF8('RoadGrade', '1')
- else if s = '二级公路' then
- FParamsNode.AttributeAddUTF8('RoadGrade', '2')
- else if s = '三级公路' then
- FParamsNode.AttributeAddUTF8('RoadGrade', '3')
- else if s = '四级公路' then
- FParamsNode.AttributeAddUTF8('RoadGrade', '4')
- else
- FParamsNode.AttributeAddUTF8('RoadGrade', '0'); // '高速公路'
- FParamsNode.AttributeAddUTF8('DesignSpeed', PV('Speed'));
- FParamsNode.AttributeAddUTF8('Structure', '0');//PV('RoadSurface'); // 取路面结构。沥青路面取0;水泥混凝土路面取1;其他类型路面取2。(现在软件中不是下拉)
- FParamsNode.AttributeAddUTF8('SubgradeWidth', PV('RoadWidth', '0'));
- FParamsNode.AttributeAddUTF8('RoadLength', PV('RoadLength', '0'));
- FParamsNode.AttributeAddUTF8('BridgeLength', PV('BridgeLength', '0'));
- FParamsNode.AttributeAddUTF8('TunnelLength', PV('TunnelLength', '0'));
- FParamsNode.AttributeAddUTF8('BriTunRate', PV('BridgeRatio', '0'));
- FParamsNode.AttributeAddUTF8('InterchangeNum', PV('CrossNum', '0'));
- FParamsNode.AttributeAddUTF8('StubLengths', PV('BranchLength', '0'));
- FParamsNode.AttributeAddUTF8('LaneLength', PV('SideRoadLength', '0'));
- FParamsNode.AttributeAddUTF8('RisingRate', FloatToStr(ScRoundTo(PD.RaiseRateByYear * 100, -2)));
- FParamsNode.AttributeAddUTF8('RisingYears', FloatToStr(PD.RaiseYear));
- FParamsNode.AttributeAddUTF8('RateNo', IntToStr(AFileNo)); //sTemp;
- FParamsNode.AttributeAddUTF8('PractNo', IntToStr(AFileNo)); //'JGXX-440000-2019-05';
- end;
- // 导出清单
- procedure TqgXMLPort.AddItems;
- var iBillCount, iTotalCount: Integer;
- // 递归1:遍历读取清单
- procedure ReadTreeNodes(ANode: TScBillsItem; AParentXMLNode: TXmlNode);
- var vItemNode, vCC, vCS, vCItem, vDD, vGC: TXmlNode;
- bHasExpr, bHasRation: Boolean;
- i: Integer;
- vFunc: TFunction;
- begin
- if ANode <> nil then
- begin
- Inc(iBillCount);
- AddProgressForm(1, Format('导出清单[%d/%d] %s %s', [iBillCount, iTotalCount, ANode.Code + ANode.B_Code, ANode.Name]));
- vItemNode := AddItem(ANode, AParentXMLNode);
- if (ANode.IsLeaf and (FFileType = xftTB)) then
- begin
- // ANode.IsCalcExprs 会漏掉纯四则运算表达式。如 1924*48+20.73*20400。
- // bHasExpr := ANode.IsCalcExprs;
- bHasExpr := TScProject(FProject).Exprs.GetExprs(ExprsID_Bills, ExprsID_Bills_TotalPrice, ANode.ID, 0) <> '';
- // 投标项目的最后一行清单"投标价"(id=9)的公式固定在代码中。如果被用户手工修改过,才会存储在公式表里。
- if (not bHasExpr) and IsSpecialFormulaBill(ANode) then bHasExpr := True;
- bHasRation := ANode.HasRations;
- if bHasExpr or bHasRation then
- begin
- vCC := vItemNode.NodeNewUTF8('CostComposition');
- if bHasExpr then
- begin
- AddFormula(ANode, vCC);
- if ANode.ID = idBuildLoanItem then
- AddBuildLoan(vCC);
- end
- else if bHasRation then
- AddRations(ANode, vCC);
- end;
- if CanGC(ANode) then
- begin
- vGC := vItemNode.NodeNewUTF8('GCTree');
- AddGC(vGC, ANode.ID);
- end;
- end;
- vCS := vItemNode.NodeNewUTF8('CostStructure');
- // 清单的费用组成
- for i := Low(Map_RationFees) to High(Map_RationFees) do
- begin
- vCItem := vCS.NodeNewUTF8('CostItem');
- vCItem.AttributeAddUTF8('ItemNo', Map_RationFees[i][1]);
- if FFileType = xftTB then
- begin
- vFunc := TFunction(ANode.GetMethod('Get' + Map_RationFees[i][0]));
- vCItem.AttributeAddUTF8('Sum', CheckNull(FloatToStr(vFunc())));
- end
- else
- vCItem.AttributeAddUTF8('Sum', '0');
- end;
- vDD := vItemNode.NodeNewUTF8('DesignDetails');
- AddDrawQ(ANode, vDD);
- if not ANode.IsLeaf then
- begin
- ReadTreeNodes(TScBillsItem(ANode.FirstChild), vItemNode);
- end;
- ReadTreeNodes(TScBillsItem(ANode.NextSibling), AParentXMLNode);
- end;
- end;
- // 递归2:遍历汇总清单的各费
- procedure CalcBillsFees(AItem: TScBillsItem);
- var i, j: Integer;
- vChild: TScBillsItem;
- vProc: TProcedure;
- vFunc1, vFunc2: TFunction;
- fTemp,fF1, fF2: Double;
- begin
- if AItem = nil then Exit;
- CalcBillsFees(TScBillsItem(AItem.FirstChild));
- Inc(iBillCount);
- AddProgressForm(1, Format('汇总清单各项费用[%d/%d] %s %s', [iBillCount, iTotalCount, AItem.Code + AItem.B_Code, AItem.Name]));
- if AItem.IsLeaf = True then
- begin
- FSearch1.Close;
- FSearch1.SQL.Clear;
- // 有定额的清单
- if AItem.HasRations then
- begin
- FSearch1.SQL.Text :=
- 'SELECT BillsItemID, Sum(LabourFee) as RGF,' +
- 'Sum(MaterialFee) as CLF, Sum(MachineFee) as JXSYF, ' +
- 'Sum(DirectFee) as ZJF , Sum(RationDirectFee) as DEZJF , ' +
- 'Sum(OtherDirectFee) as CSF,' +
- 'IIF(Sum(OtherFee1) is null, 0, Sum(OtherFee1)) as CSF1, ' +
- 'IIF(Sum(OtherFee2) is null, 0, Sum(OtherFee2)) as CSF2, ' +
- 'IIF(Sum(ManageFee) is null, 0, Sum(ManageFee)) as QYGLF, ' +
- 'Sum(LocaleFee) as GF,' +
- 'Sum(Profit) as LR, Sum(Tax) as SJ, ' +
- 'Sum(RationBuildingFee) as DEJAF, Sum(BuildingFee) as JAF ' +
- 'From RationCalclist where BillsItemID=' + IntToStr(AItem.ID) +
- ' Group by BillsItemID';
- FSearch1.Open;
- if FSearch1.RecordCount > 0 then
- begin
- // eg: AItem.LabourFee := FSearch1.FieldByName('RGF').AsFloat; ...
- for j := Low(Map_RationFees) to High(Map_RationFees) do
- begin
- vProc := TProcedure(AItem.GetMethod('Set' + Map_RationFees[j][0]));
- vProc(FSearch1.FieldByName(Map_RationFees[j][1]).AsFloat);
- end;
- end
- end
- // 公式清单、量价式清单
- else
- begin
- FSearch1.SQL.Text :=
- 'SELECT RationTotalPrice as DEJAF, TotalPrice as JAF ' +
- 'From Bills where ID=' + IntToStr(AItem.ID);
- FSearch1.Open;
- if FSearch1.RecordCount > 0 then
- begin
- vProc := TProcedure(AItem.GetMethod('SetRationBuildingFee'));
- vProc(FSearch1.FieldByName('DEJAF').AsFloat);
- vProc := TProcedure(AItem.GetMethod('SetBuildingFee'));
- vProc(FSearch1.FieldByName('JAF').AsFloat);
- end
- end;
- FSearch1.Close;
- end
- else
- begin
- // AItem.LabourFee := 0; AItem.MaterialFee := 0;...
- for j := Low(Map_RationFees) to High(Map_RationFees) do
- begin
- vProc := TProcedure(AItem.GetMethod('Set' + Map_RationFees[j][0]));
- vProc(0);
- end;
- // AItem.LabourFee := AItem.LabourFee + vChild.LabourFee; AItem.MaterialFee := AItem.MaterialFee + vChild.MaterialFee; ...
- for i := 0 to AItem.ChildCount - 1 do
- begin
- vChild := TScBillsItem(AItem.ChildNodes[i]);
- for j := Low(Map_RationFees) to High(Map_RationFees) do
- begin
- vFunc1 := TFunction(AItem.GetMethod('Get' + Map_RationFees[j][0]));
- vFunc2 := TFunction(vChild.GetMethod('Get' + Map_RationFees[j][0]));
- fF1 := vFunc1();
- fF2 := vFunc2();
- fTemp := fF1 + fF2;
- vProc := TProcedure(AItem.GetMethod('Set' + Map_RationFees[j][0]));
- vProc(fTemp);
- end;
- end;
- end;
- CalcBillsFees(TScBillsItem(AItem.NextSibling));
- end;
- var vTree: TScBillsTree;
- begin
- FItemsNode := FEprjInfoNode.NodeNewUTF8('Items');
- vTree := TScProject(FProject).Bills.BillsTree;
- iTotalCount := vTree.Count;
- AddProgressForm(10, '汇总清单各项费用...');
- iBillCount := 0;
- if (FFileType <> xftZB) then
- CalcBillsFees(vTree.Items[0]);
- AddProgressForm(10, '导出清单...');
- iBillCount := 0;
- ReadTreeNodes(vTree.Items[0], FItemsNode);
- end;
- procedure TqgXMLPort.AddNodes;
- var
- n: Integer;
- isNewOpen: Boolean;
- begin
- inherited;
- AddCprjInfo;
- AddDecimalOption;
- AddSystemInfo;
- AddCostBasis;
- AddMultiProjects;
- AddIndexs;
- end;
- // 目的是容错处理。有的清单该输入的编号没输入,导致ItemType识别不准,导入云版后树结构会出现错误。
- // 该方法去掉递归:总会有各种情况导致递归死循环。
- function TqgXMLPort.GetItemTypeByCode(AItem: TScBillsItem): string;
- // 是否两个编号都为空
- function IsNoCode(Item: TScBillsItem): Boolean;
- begin
- Result := ((Rec(Item, 'B_Code') = '') and (Rec(Item, 'Code') = ''));
- end;
- // 只通过自己判断,不依赖父、前后兄弟。
- function GetItemTypeBySelf(Item: TScBillsItem): string;
- begin
- if (Rec(Item, 'B_Code') <> '') then
- Result := '1'
- else
- Result := '0';
- end;
- var vItem: TScBillsItem;
- begin
- // 两个编号都为空时,要依赖父、前后兄弟判断。
- if IsNoCode(AItem) then
- begin
- if Assigned(AItem.PrevSibling) then // 如果有前兄弟,就按前兄弟
- begin
- vItem := TScBillsItem(AItem.PrevSibling);
- if IsNoCode(vItem) then // 如果前兄弟不靠谱,就按父结点
- vItem := TScBillsItem(AItem.Parent);
- end
- else if Assigned(AItem.NextSibling) then // 如果有后兄弟,就按后兄弟
- begin
- vItem := TScBillsItem(AItem.NextSibling);
- if IsNoCode(vItem) then // 如果后兄弟不靠谱,就按父结点
- vItem := TScBillsItem(AItem.Parent);
- end
- else if Assigned(AItem.Parent) then // 如果没有兄弟结点,就按父结点
- begin
- vItem := TScBillsItem(AItem.Parent);
- end;
-
- if Assigned(vItem) then // 到了这一层就结束,只按自己判断
- begin
- Result := GetItemTypeBySelf(vItem);
- end
- else
- Result := '0';
- end
- else
- Result := GetItemTypeBySelf(AItem);
- end;
- function TqgXMLPort.AddItem(ANode: TScBillsItem;
- AParentXMLNode: TXmlNode): TXmlNode;
- var sExpr, sCode, sMapValue, sMapName, sIT, sQty: string;
- begin
- Result := AParentXMLNode.NodeNewUTF8('Item');
- Result.AttributeAddUTF8('ListCode', ANode.SmartCode);
- Result.AttributeAddUTF8('ListName', Rec(ANode, 'Name'));
- Result.AttributeAddUTF8('Unit', ChangeUnit_m3(Rec(ANode, 'Units')));
- sExpr := '';
- if (TScProject(FProject).ProjType in [ptBudget, ptBudgetEstimate, ptFeasibilityEstimate, ptProposalEstimate]) then
- begin
- Result.AttributeAddUTF8('Num', CheckNull(ANode.Rec.DesignQuantity.AsString));
- Result.AttributeAddUTF8('Num1', CheckNull(ANode.Rec.DesignQuantity.AsString));
- Result.AttributeAddUTF8('Num2', CheckNull(ANode.Rec.DesignQuantity2.AsString));
- sExpr := TScProject(FProject).Exprs.GetExprs(ExprsID_Bills, ExprsID_Bills_DesignQuantity, ANode.ID, 0);
- Result.AttributeAddUTF8('NumExpression', sExpr);
- end
- else if (TScProject(FProject).ProjType = ptBillsBudget) then // 三级清单项目
- begin
- if (ANode.B_Code <> '') then // 清单
- begin
- sQty := CheckNull(ANode.Rec.Quantity.AsString);
- sExpr := TScProject(FProject).Exprs.GetExprs(ExprsID_Bills, ExprsID_Bills_Quantity, ANode.ID, 0);
- {三级清单项目,清单工程量为0或空的情况: 用的是反算时,导出时,判断叶子清单,如果金额≠0,
- 且没有基数计算,且工程量为0或空,则导出时工程量给定1。
- 其他类型项目不处理,因验证了单机版和云版,工程量为0时,金额也是0。只有三级清单特殊 }
- if (sQty = '0') and (sExpr = '') and (Rec(ANode, 'TotalPrice') <> '0')
- and (TScProjBaseData(TScProject(FProject).ProjData).Properties.UnitPriceMode = 1)
- and (ANode.IsLeaf = True)
- then sQty := '1';
- Result.AttributeAddUTF8('Num', sQty);
- Result.AttributeAddUTF8('Num1', sQty);
- Result.AttributeAddUTF8('NumExpression', sExpr);
- end
- else // 项目节
- begin
- Result.AttributeAddUTF8('Num', CheckNull(ANode.Rec.DesignQuantity.AsString));
- Result.AttributeAddUTF8('Num1', CheckNull(ANode.Rec.DesignQuantity.AsString));
- Result.AttributeAddUTF8('Num2', CheckNull(ANode.Rec.DesignQuantity2.AsString));
- sExpr := TScProject(FProject).Exprs.GetExprs(ExprsID_Bills, ExprsID_Bills_DesignQuantity, ANode.ID, 0);
- Result.AttributeAddUTF8('NumExpression', sExpr);
- end;
- Result.AttributeAddUTF8('BillBudgetFlag', CheckBool(Rec(ANode, 'IsQDYS')));
- end
- else if (TScProject(FProject).ProjType = ptBills) then
- begin
- Result.AttributeAddUTF8('Num', CheckNull(ANode.Rec.Quantity.AsString));
- Result.AttributeAddUTF8('Num1', CheckNull(ANode.Rec.Quantity.AsString));
- sExpr := TScProject(FProject).Exprs.GetExprs(ExprsID_Bills, ExprsID_Bills_Quantity, ANode.ID, 0);
- Result.AttributeAddUTF8('NumExpression', sExpr);
- end;
- if FFileType = xftTB then
- Result.AttributeAddUTF8('Price', CheckNull(FloatToStr(ANode.SmartPrice)))
- else
- Result.AttributeAddUTF8('Price', '0');
- if FFileType = xftTB then
- Result.AttributeAddUTF8('Sum', Rec(ANode, 'TotalPrice'))
- else
- Result.AttributeAddUTF8('Sum', '0');
- if ANode.Rec.ValueByName('InterimType').AsInteger > 0 then
- Result.AttributeAddUTF8('ProvisionalType', IntToStr(ANode.Rec.ValueByName('InterimType').AsInteger - 1));
- Result.AttributeAddUTF8('Remarks', Rec(ANode, 'MemoStr'));
- Result.AttributeAddUTF8('MpRatio', CheckNull(Rec(ANode, 'XS_Labour')));
- Result.AttributeAddUTF8('MaterialRatio', CheckNull(Rec(ANode, 'XS_Material')));
- Result.AttributeAddUTF8('MechRatio', CheckNull(Rec(ANode, 'XS_Machine')));
- Result.AttributeAddUTF8('AdjustedPrice', CheckNull(Rec(ANode, 'TenderUnitPrice')));
- Result.AttributeAddUTF8('AdjustedSums', CheckNull(Rec(ANode, 'TenderTotalPrice')));
- // ItemType,清单1,预算项目节0。
- if TScProject(FProject).IsBills then
- sIT := '1'
- else if TScProject(FProject).IsBudget then
- sIT := '0'
- else // 三级清单
- sIT := GetItemTypeByCode(ANode);
- Result.AttributeAddUTF8('ItemType', sIT);
- // 清单行的FormulaCode属性,用作行引用:有@ID和字母(不需要{})两种形式。
- if ANode.ID = 1 then // ID为1的清单(@1)不能给成 GZQDHJ,否则云版计算会死循环
- begin
- if TScProject(FProject).IsBills then
- sCode := 'D100Z700'
- else
- sCode := 'DYBF';
- end
- else
- begin
- sCode := '@' + IntToStr(ANode.ID);
- if TScProject(FProject).IsBills then
- sMapName := 'Map_Formula_Bill'
- else
- sMapName := 'Map_Formula_Budget';
- sMapValue := GetMapValue(GetMap(sMapName), sCode, 0, 2); // 返回 {ZXZDHJ}
- if sMapValue <> '' then
- sCode := Copy(sMapValue, 2, Length(sMapValue) - 2); // 去掉{}
- end;
- Result.AttributeAddUTF8('FormulaCode', sCode);
- end;
- function TqgXMLPort.GetNormLibNoByID(ALibID: Integer): string;
- var sLibName: string;
- begin
- IntToIdent(ALibID, sLibName, FLibArr);
- Result := GetMapValue(GetMap('Map_RationLib'), sLibName);
- end;
- function TqgXMLPort.GetGJLCodeByKey(AKey: string; AOrgCode: string): string;
- var sNewCode: string;
- begin
- sNewCode := FGLJKeyCodeMap.Values[AKey];
- if sNewCode = '' then sNewCode := AOrgCode;
- Result := sNewCode;
- end;
- function TqgXMLPort.GetType(AType, ACalculateType: Integer; AName: string): Integer;
- begin
- case AType of
- 1:
- begin
- if AName = '机械工' then Result := 303
- else Result := AType;
- end;
- 2:
- begin
- if ACalculateType = 0 then Result := 202 // 混凝土
- else Result := AType;
- end;
- 3, 4: // 3 兼容旧项目材料
- begin
- if (ACalculateType = 0) or (ACalculateType = -1) then Result := 201 // 普通材料
- else if ACalculateType = 1 then Result := 205 // 商品砼
- else if ACalculateType = 2 then Result := 208 // 预制构件
- else if ACalculateType = 3 then Result := 209 // 绿化苗木
- else if ACalculateType = 4 then Result := 206 // 路基填料
- else if ACalculateType = 5 then Result := 206 // 商品沥青混合料
- else if ACalculateType = 6 then Result := 206 // 各类稳定土混合料
- else Result := AType;
- end;
- 6:
- begin
- if ACalculateType = 0 then Result := 5 // 设备
- else Result := AType;
- end;
- else
- Result := AType;
- end;
- end;
- // 投标项目, 特殊的清单,公式写死在代码里,用户也可以自定义。如:最后一行清单"投标价"(id=9)等。
- function TqgXMLPort.IsSpecialFormulaBill(ANode: TScBillsItem): Boolean;
- begin
- Result := IsSpecialFormulaBill(ANode.ID);
- end;
- function TqgXMLPort.IsSpecialFormulaBill(ABillID: Integer): Boolean;
- begin
- Result := (TScProject(FProject).ProjType = ptBills) and
- (ABillID in [idSpecialInterimSum, idBillSumExcludeSpecialInterim, idProjectTotalPrice_Bills]);
- end;
- procedure TqgXMLPort.AddDrawQ(ANode: TScBillsItem; AParentXMLNode: TXmlNode);
- var vChild: TXmlNode;
- begin
- FQuery2.Close;
- FQuery2.SQL.Clear;
- FQuery2.SQL.Add(Format('SELECT * FROM DrawingQuantity WHERE BillsID = %d', [ANode.ID]));
- FQuery2.Open;
- if FQuery2.RecordCount > 0 then
- begin
- FQuery2.First;
- while not FQuery2.Eof do
- begin
- vChild := AParentXMLNode.NodeNewUTF8('DesignDetail');
- vChild.AttributeAddUTF8('OrderNumber', IntToStr(FQuery2.RecNo));
- vChild.AttributeAddUTF8('Name', FQuery2.FieldByName('Name').asString);
- vChild.AttributeAddUTF8('Unit', ChangeUnit_m3(FQuery2.FieldByName('Units').asString));
- vChild.AttributeAddUTF8('Express', FQuery2.FieldByName('ExprsMemo').asString);
- vChild.AttributeAddUTF8('DesignQuantity', FQuery2.FieldByName('DQuantity1').asString);
- // vChild.AttributeAddUtf8('Kind', '2');
- vChild.AttributeAddUTF8('Remark', FQuery2.FieldByName('MemoContext').asString);
- FQuery2.Next;
- end;
- end;
- FQuery2.Close;
- end;
- function TqgXMLPort.AdjustStateToPort(ARation: TScRationRecord): string;
- var vSL: TStringList;
- i: Integer;
- sAdjustState, sOneState, sTemp: string;
- begin
- sAdjustState := ARation.AdjustState.AsString;
- if Trim(sAdjustState) = '' then
- begin
- Result := '';
- Exit;
- end;
-
- vSL := TStringList.Create;
- try
- vSL.Delimiter := ';';
- vSL.DelimitedText := sAdjustState;
- for i := 0 to vSL.Count - 1 do
- begin
- sOneState := vSL[i];
- vSL[i] := OneAdjustToPort(sOneState, ARation); // 每项可读可改
- end;
- vSL.Delimiter := ';'; // 重新指定新的分隔符
- Result := vSL.DelimitedText; // 改后的每项重新合成新串
- finally
- vSL.Free;
- end;
- // 辅助定额特殊处理:追加定额编号。这个逻辑不能在分段 OneAdjustToPort()中处理,因为会重复。在这里只加一次搞定。
- if Pos('+', Result) > 0 then
- begin
- sTemp := ARation.Code.AsString + ' ' + '+';
- Result := StringReplace(Result, '+', sTemp, []);
- end;
- end;
- (*------------------------------------------------------------------------------
- 单机导出部颁接口,定额调整文本,按以下规则输出:
- (1)按“;”将调整状态拆分为多个。
- (2)辅助定额,单条,显示格式为“2-2-13-1 +2×8”(定额的编号,不是辅助定额的编号)。多条,显示格式为“2-2-13-1 +5×9; +4×3; +6×27”
- (3)自定义消耗量,显示格式为“[2005001]10.5量10.2”。
- (4)添加材料,显示格式为“[2005001]0量10.2”。
- (5)替换材料,工程量不变,显示格式为“[2009028]换[2009029]”。工程量变化,显示格式为“[2009028]0.89换[2009029]1.025”。
- (6)稳定土配合比,显示格式为“配比[5501002:5503004:5509001]=[10:79:11]”。
- (7)附注条件,显示格式为“人、机械、小型机具使用费×1.26”、“定额×0.73”,即附注条件的内容列。
- (8)自定义系数,显示格式为“定额×2”、“工×2”、“料×1.1”、“机×1.5”。
- (9)油石比,显示格式为“配比[3001001]=5.45”。
- (10)处理材料编号。比如原文本是“[2009028]换[2009029]”,但导出接口时,2009029重编为2009029-1了;文本应更为“[2009028]换[2009029-1]”。
- ------------------------------------------------------------------------------*)
- function TqgXMLPort.OneAdjustToPort(AOneState: string; ARation: TScRationRecord): string;
- var sRCode, sGLJCode, sQty, sTemp, sHint: string;
- iPos1, iPos2, RID: Integer;
- RAdjData: TScRAdjustData;
- GLJRec: TScGLJRecord;
- f: Double;
- begin
- Result := AOneState;
- if AOneState = '' then Exit;
- // 思路:典型的、确定可靠的先挑出来,避免干扰。
- RAdjData := TScProject(FProject).Rations.RAdjusts;
- RID := ARation.ID.AsInteger;
- // 辅助定额:加定额编号。注意!这里先不加,因为多条辅助定额时会加重复。解决:在完整的调整状态位置,在第一个加号前加一次即可。
- if AOneState[1] = '+' then
- begin
- Result := AOneState;
- end
- // 附注条件:原样输出
- else if (Pos(',', AOneState) > 0) or (Pos(',', AOneState) > 0) then
- begin
- Result := AOneState;
- end
- // 配比:80:20 →配比[5501002:5503004:5509001]=[10:79:11]
- else if Pos(':', AOneState) > 0 then
- begin
- Result := RAdjData.getPortAdjustState_PB(RID);
- end
- // 添加材料:添2003064量24 →[2003064]0量24
- else if (Pos('添', AOneState) = 1) then
- begin
- Result := StringReplace(AOneState, '添', '[', []);
- Result := StringReplace(Result, '量', ']0量', []);
- end
- // 油石比/自定义消耗量 两个货长一样:
- // 油石比: 3001001量23 →配比[3001001]=5.45
- // 自定义消耗量: 2009028量23 →[2009028]18量23
- else if (Pos('量', AOneState) > 0) and (Pos(',', AOneState) = 0) then
- begin
- sGLJCode := Copy(AOneState, 1, Pos('量', AOneState) - 1);
- f := RAdjData.getPortAdjustState_YS(RID);
- if (f <> 0) then // 有油石比数据
- begin
- Result := Format('配比[%s]=%s', [sGLJCode, FloatToStr(f)]); // %f 有无法指定小数位数问题,直接搞成%s省心。
- end
- else
- begin
- GLJRec := TScProject(FProject).GLJ.FindGLJByRationIDAndGLJCode(RID, sGLJCode);
- if not Assigned(GLJRec) then // 遇到过新工料机找不到的情况。
- begin
- sHint := Format('找不到工料机 %s :[标段]%s [定额]%s [工程量]%s',
- [sGLJCode, FEprjInfoNode.AttributeValueByNameUTF8['Name'], ARation.Code.AsString, ARation.Quantity.AsString]);
- MessageWarning(sHint);
- sQty := '??';
- end
- else
- begin
- sQty := GLJRec.OrgRQuantity.AsString;
- end;
- sTemp := ']' + sQty + '量';
- Result := StringReplace(AOneState, '量', sTemp, []);
- Result := '[' + Result;
- end;
- end
- // 替换材料: 2003008换2003009 →[2003008]换[2003009]
- // 替换材料2: 2003008换2003009; 2003009量6 →[2003008]0.89换[2003009]6
- else if Pos('换', AOneState) > 0 then
- begin
- Result := StringReplace(AOneState, '换', ']换[', []);
- sTemp := Copy(Result, 1, Pos(']', Result) - 1); // "换"字前的 编号/简称/名称
- if not IsNumberStr(sTemp) then
- begin
- // 替换简称、名称,如:'M10]换[M20'、'水C25-32.5-4]换[水C30-32.5-4'
- Result := StringReplace(Result, sTemp, SearchDic_Concrete(sTemp, 2, 0), []);
- iPos2 := Pos('[', Result);
- sTemp := Copy(Result, iPos2 + 1, Length(Result) - iPos2);
- Result := StringReplace(Result, sTemp, SearchDic_Concrete(sTemp, 2, 0), []);
- end;
- Result := Format('[%s]', [Result]);
- end
- // 自定义系数:这种也是直接出。(附注条件含的,已经在前面过滤掉了)
- else if (Pos('定额×', AOneState) = 1) then
- begin
- Result := AOneState;
- end
- // 自定义系数
- else if (Pos('人工×', AOneState) = 1) or (Pos('材料×', AOneState) = 1)
- or (Pos('机械×', AOneState) = 1) then
- begin
- Result := StringReplace(AOneState, '人工×', '工×', []);
- Result := StringReplace(Result, '材料×', '料×', []);
- Result := StringReplace(Result, '机械×', '机×', []);
- end
- // 搞不定的都在这儿
- else
- begin
- Result := AOneState;
- end;
- end;
- procedure TqgXMLPort.AddBuildLoan(AParentXMLNode: TXmlNode);
- var vBuildLoan, vBanks, vYear: TXmlNode;
- sMethod, sName, sYun, sValue: string;
- begin
- vBuildLoan := AParentXMLNode.NodeNewUTF8('LoanDetails');
- FSearch1.Close;
- FSearch1.SQL.Text := 'Select ItemValue From ProjProperty Where Name=''BUILDLOANCALCMODE''';
- FSearch1.Open;
- sValue := FSearch1.FieldByName('ItemValue').AsString;
- if sValue = '1' then // 固定金额
- sMethod := '3'
- else
- begin
- FSearch1.Close;
- FSearch1.SQL.Text := 'Select ItemValue From ProjProperty Where Name=''BUILDLOANEXPMODE''';
- FSearch1.Open;
- sValue := FSearch1.FieldByName('ItemValue').AsString;
- if sValue = '0' then
- sMethod := '1' // 基数比例-总造价比例
- else
- sMethod := '2'; // 基数比例-一二三部分合计比例
- end;
- vBuildLoan.AttributeAddUTF8('LoanMethod', sMethod);
- FSearch1.Close;
- FSearch1.SQL.Text := 'Select ItemValue From ProjProperty Where Name=''BUILDLOANTOTALPROPORTION''';
- FSearch1.Open;
- sValue := FSearch1.FieldByName('ItemValue').AsString;
- vBuildLoan.AttributeAddUTF8('LoanRatio', sValue);
- FSearch1.Close;
- FSearch1.SQL.Text := 'Select ItemValue From ProjProperty Where Name=''DEDUCTEXPR''';
- FSearch1.Open;
- vBuildLoan.AttributeAddUTF8('SubsidyDeduction', FSearch1.FieldByName('ItemValue').AsString);
- FSearch1.Close;
- FSearch1.SQL.Text := 'Select Sum(BankMoney) as total From ProjInfo';
- FSearch1.Open;
- vBuildLoan.AttributeAddUTF8('TotalLoans', FSearch1.FieldByName('total').AsString);
- FSearch1.Close;
- FSearch1.SQL.Text := 'Select * From ProjInfo';
- FSearch1.Open;
- FSearch1.First;
- while not FSearch1.Eof do
- begin
- vBanks := vBuildLoan.NodeNewUTF8('Banks');
- vBanks.AttributeAddUTF8('BankName', FSearch1.FieldByName('ProjName').AsString);
- vBanks.AttributeAddUTF8('BankRatio', FSearch1.FieldByName('BankProportion').AsString);
- vBanks.AttributeAddUTF8('BankLoanAmount', FSearch1.FieldByName('BankMoney').AsString);
- vBanks.AttributeAddUTF8('InterestBearingYear', FSearch1.FieldByName('Years').AsString);
- FSearch2.Close;
- FSearch2.SQL.Text := 'Select * From YearLoan where ProjID=' + FSearch1.FieldByName('ProjID').AsString + ' order by YearNo';
- FSearch2.Open;
- FSearch2.First;
- while not FSearch2.Eof do
- begin
- vYear := vBanks.NodeNewUTF8('InterestDetails');
- vYear.AttributeAddUTF8('Annual', FSearch2.FieldByName('YearNo').AsString);
- vYear.AttributeAddUTF8('AnnualName', FSearch2.FieldByName('YearName').AsString);
- vYear.AttributeAddUTF8('AnnualRatio', FSearch2.FieldByName('YearProportion').AsString);
- vYear.AttributeAddUTF8('AnnualLoanAmount', FSearch2.FieldByName('Principal').AsString);
- vYear.AttributeAddUTF8('InterestRate', FSearch2.FieldByName('InterestRate').AsString);
- // vYear.AttributeAddUtf8('LastYearsPI', FSearch2.FieldByName('LastYearsPI').AsString);
- vYear.AttributeAddUTF8('Interest', FSearch2.FieldByName('Interest').AsString);
- FSearch2.Next;
- end;
- FSearch1.Next;
- end;
- FSearch1.Close;
- FSearch2.Close;
- end;
- function TqgXMLPort.CanGC(ANode: TScBillsItem): Boolean;
- var b: Boolean;
- begin
- Result := False;
- if TScProject(FProject).IsBills then Exit;
- if not TScProject(FProject).IsGuangDong then Exit;
- // idSurveyDesign、 idSupervisionService 这两个不管。只导出3种树
- if ANode.IsInheritFrom(idGroundCompensate) or
- ANode.IsInheritFrom(idGroundRemove) or
- ANode.IsInheritFrom(idGroundTemporary) then
- Result := True;
- end;
- procedure TqgXMLPort.AddGC(AParentXMLNode: TXMLNode; const ABillsID: Integer);
- var vItem: TScBillsItem;
- vTree: TBaseTree;
- vFirst, vLast: TBaseNode;
- begin
- vItem := TScProject(FProject).Bills.BillsTree[ABillsID];
- if not vItem.HasLeafTree then Exit;
- vTree := TScProject(FProject).LeafTreesDM.TreeManager.IDItem[ABillsID];
- if vTree.Count < 1 then Exit;
- AParentXMLNode.AttributeAddUTF8(c_TreeType, IntToStr(vTree.TreeType));
- vFirst := TBaseNode(vTree[0]);
- vLast := vFirst;
- while Assigned(vLast.NextSibling) do
- vLast := TBaseNode(vLast.NextSibling);
- AddGC2(vTree, vFirst.MajorIndex, vLast.MajorIndex, AParentXMLNode);
- end;
- // AGCNode比AXMLNode高一级别
- procedure TqgXMLPort.AddGC2(ALeafTree: TBaseTree; AIndex1, AIndex2: Integer; AXMLNode: TXmlNode);
- var
- vXMLCurNode: TXmlNode;
- vGCNode: TBaseNode;
- iIndex: Integer;
- function AddGC3(ANode: TBaseNode; AXMLNode: TXmlNode): TXMLNode;
- var
- vXMLNode: TXmlNode;
- procedure AssignBaseProperty(AXMLNode: TXmlNode; ANode: TBaseNode);
- begin
- AXMLNode.AttributeAddUTF8('Code', ANode.Code);
- AXMLNode.AttributeAddUTF8('Name', ANode.Name);
- AXMLNode.AttributeAddUTF8('Units', ANode.Units);
- AXMLNode.AttributeAddUTF8('Quantity', FloatToStr(ANode.Quantity));
- AXMLNode.AttributeAddUTF8('UnitPrice', FloatToStr(ANode.UnitPrice));
- AXMLNode.AttributeAddUTF8('TotalPrice', FloatToStr(ANode.TotalPrice));
- AXMLNode.AttributeAddUTF8('MemoStr', ANode.MemoStr);
- AXMLNode.AttributeAddUTF8('IsLeaf', BoolToStr(ANode.IsLeaf));
- end;
- function GetGroundKindName(ANode: TGCNode): string;
- begin
- Result := ANode.GroundKindName;
- if Result = '' then
- Result := '耕地';
- end;
- procedure AssignGCProperty(AXMLNode: TXmlNode; ANode: TGCNode);
- begin
- AXMLNode.AttributeAddUTF8(c_GroundCompSubtotal, CurrToStr(ANode.GroundCompSubtotal));
- AXMLNode.AttributeAddUTF8(c_SeedlingCompSubtotal, CurrToStr(ANode.SeedlingCompSubtotal));
- AXMLNode.AttributeAddUTF8(c_InsurePeopleCount, CurrToStr(ANode.InsurePeopleCount));
- AXMLNode.AttributeAddUTF8(c_OtherFeeSubtotal, CurrToStr(ANode.OtherFeeSubtotal));
- // AXMLNode.AttributeAddUtf8(c_InsureSubtotal, CurrToStr(ANode.InsureSubtotal)); 2011年的算法,现在不用了,不导出。
- AXMLNode.AttributeAddUTF8(c_GroundTaxFeeSubtotal, CurrToStr(ANode.GroundTaxFeeSubtotal));
- AXMLNode.AttributeAddUTF8(c_SeedlingCompFee, CurrToStr(ANode.SeedlingCompFee));
- AXMLNode.AttributeAddUTF8(c_GroundCompFee, CurrToStr(ANode.GroundCompFee));
- AXMLNode.AttributeAddUTF8(c_TilthAmountPerPeople, CurrToStr(ANode.TilthAmountPerPeople));
- AXMLNode.AttributeAddUTF8(c_ExtractBase, CurrToStr(ANode.ExtractBase));
- AXMLNode.AttributeAddUTF8(c_ExtractRatio, CurrToStr(ANode.ExtractRatio));
- AXMLNode.AttributeAddUTF8(c_Resettle, CurrToStr(ANode.Resettle));
- AXMLNode.AttributeAddUTF8(c_ExtractSubtotal, CurrToStr(ANode.ExtractSubtotal));
- AXMLNode.AttributeAddUTF8(c_AreaStandard, CurrToStr(ANode.AreaStandard));
- AXMLNode.AttributeAddUTF8(c_AgricultureTax, CurrToStr(ANode.AgricultureTax));
- AXMLNode.AttributeAddUTF8(c_TilthImprTax, CurrToStr(ANode.TilthImprTax));
- AXMLNode.AttributeAddUTF8(c_TilthAssartFee, CurrToStr(ANode.TilthAssartFee));
- AXMLNode.AttributeAddUTF8(c_ForestRecoverFee, CurrToStr(ANode.ForestRecoverFee));
- AXMLNode.AttributeAddUTF8(c_GroundRepayUseFee, CurrToStr(ANode.GroundRepayUseFee));
- AXMLNode.AttributeAddUTF8(c_GroundManageFee, CurrToStr(ANode.GroundManageFee));
- AXMLNode.AttributeAddUTF8(c_LeftGroundFee, CurrToStr(ANode.LeftGroundFee));
- AXMLNode.AttributeAddUTF8(c_GroundSurveyFee, CurrToStr(ANode.GroundSurveyFee));
- AXMLNode.AttributeAddUTF8(c_GroundKindID, IntToStr(ANode.GroundKindID));
- AXMLNode.AttributeAddUTF8(c_AreaCategoryID, IntToStr(ANode.AreaCategoryID));
- AXMLNode.AttributeAddUTF8(c_IsProtectedArea, BoolToStr(ANode.IsProtectedArea));
- AXMLNode.AttributeAddUTF8(c_IsPaddyField, BoolToStr(ANode.IsPaddyField));
- AXMLNode.AttributeAddUTF8(c_AreaID, IntToStr(ANode.AreaID));
- AXMLNode.AttributeAddUTF8(c_AreaName, ANode.AreaName);
- AXMLNode.AttributeAddUTF8(c_ForestRecoverID, IntToStr(ANode.ForestRecoverID));
- AXMLNode.AttributeAddUTF8(c_IsCityForest, BoolToStr(ANode.IsCityForest));
- AXMLNode.AttributeAddUTF8(c_AreaCategoryName, ANode.AreaCategoryName);
- AXMLNode.AttributeAddUTF8(c_GroundKindName, GetGroundKindName(ANode));
- AXMLNode.AttributeAddUTF8(c_NewAddFee_GC_1, CurrToStr(ANode.NewAddFee_GC_1));
- AXMLNode.AttributeAddUTF8(c_NewAddFee_GC_2, CurrToStr(ANode.NewAddFee_GC_2));
- AXMLNode.AttributeAddUTF8(c_NewAddFee_GC_3, CurrToStr(ANode.NewAddFee_GC_3));
- AXMLNode.AttributeAddUTF8(c_NewAddFee_SC_1, CurrToStr(ANode.NewAddFee_SC_1));
- AXMLNode.AttributeAddUTF8(c_NewAddFee_SC_2, CurrToStr(ANode.NewAddFee_SC_2));
- AXMLNode.AttributeAddUTF8(c_NewAddFee_SC_3, CurrToStr(ANode.NewAddFee_SC_3));
- AXMLNode.AttributeAddUTF8(c_NewAddFee_Other_1, CurrToStr(ANode.NewAddFee_Other_1));
- AXMLNode.AttributeAddUTF8(c_NewAddFee_Other_2, CurrToStr(ANode.NewAddFee_Other_2));
- AXMLNode.AttributeAddUTF8(c_NewAddFee_Other_3, CurrToStr(ANode.NewAddFee_Other_3));
- AXMLNode.AttributeAddUTF8(c_NewAddFee_GT_1, CurrToStr(ANode.NewAddFee_GT_1));
- AXMLNode.AttributeAddUTF8(c_NewAddFee_GT_2, CurrToStr(ANode.NewAddFee_GT_2));
- AXMLNode.AttributeAddUTF8(c_NewAddFee_GT_3, CurrToStr(ANode.NewAddFee_GT_3));
- AXMLNode.AttributeAddUTF8(c_IsCountPriceMode, BoolToStr(ANode.IsCountPriceMode));
- AXMLNode.AttributeAddUTF8(c_PensionCount, CurrToStr(ANode.PensionCount));
- AXMLNode.AttributeAddUTF8(c_Age16Rate, CurrToStr(ANode.Age16Rate));
- AXMLNode.AttributeAddUTF8(c_Year15Insur, CurrToStr(ANode.Year15Insur));
- AXMLNode.AttributeAddUTF8(c_LeftGroundRate, CurrToStr(ANode.LeftGroundRate));
- AXMLNode.AttributeAddUTF8(c_IndustryLandPrice, CurrToStr(ANode.IndustryLandPrice));
- AXMLNode.AttributeAddUTF8(c_LeftGroundFee2019, CurrToStr(ANode.LeftGroundFee2019));
- AXMLNode.AttributeAddUTF8(c_PackageFee, CurrToStr(ANode.PackageFee));
- AXMLNode.AttributeAddUTF8(c_RewardFee, CurrToStr(ANode.RewardFee));
- end;
- begin
- vXMLNode := AXMLNode.NodeNewUTF8('GCNode');
- Result := vXMLNode;
- AssignBaseProperty(vXMLNode, ANode);
- if TBaseTree(ANode.Owner).TreeType = tt_GroundCompensate then
- if ANode.IsLeaf then
- AssignGCProperty(vXMLNode, TGCNode(ANode));
- end;
- begin
- if AIndex1 > AIndex2 then Exit;
- vGCNode := TBaseNode(ALeafTree.Items[AIndex1]);
- while (vGCNode <> nil) and (vGCNode.MajorIndex <= AIndex2) do
- begin
- vXMLCurNode := AddGC3(vGCNode, AXMLNode);
- if vGCNode.HasChildren then
- begin
- iIndex := vGCNode.FirstChild.MajorIndex;
- AddGC2(ALeafTree, iIndex, MaxInt, vXMLCurNode); // vXMLCurNode比当前vGCNode高一级别
- end;
- vGCNode := TBaseNode(vGCNode.NextSibling);
- end;
- end;
- procedure TqgXMLPort.AddNodesForEveryProject(n: Integer);
- begin
- inherited;
- AddRationLibs;
- AddRate(n);
- AddPract(n);
- AddEprjInfo(n);
- end;
- {TZTBXMLPort}
- procedure TZTBXMLPort.AddNodes;
- begin
- inherited;
- AddGCXX;
- AddZTBXX;
- AddGLGCSJ;
- // 修改投标总价
- if (FFileType = xftTB) then
- FZTBXX.Elements[0].AttributeValueByNameUTF8['投标总价'] := FloatToStr(FAllProjectsTotalPriceSum);
- // 修改数据校验码
- FGCXX.AttributeValueByNameUTF8['数据校验码'] := GetDataCheckCode;
- end;
- procedure TZTBXMLPort.AddNodesForEveryProject(n: Integer);
- begin
- inherited;
- AddGLBDGC(n);
- end;
- procedure TZTBXMLPort.AddGCXX;
- var s: string;
- sTemp: string;
- begin
- AddProgressForm(10, '正在生成工程信息...');
- FGCXX := FRoot.NodeNewUTF8('工程信息');
- FGCXX.AttributeAddUTF8('项目编号', BV(SProjectNo));
- FGCXX.AttributeAddUTF8('项目名称', PD.BuildProjectName);
- FGCXX.AttributeAddUTF8('建设单位', BV(SBuildUnit));
- FGCXX.AttributeAddUTF8('起始桩号', BV(SStartCode));
- FGCXX.AttributeAddUTF8('终点桩号', BV(SEndCode));
- FGCXX.AttributeAddUTF8('建设地址', BV(SProjectLocation));
- FGCXX.AttributeAddUTF8('项目概况', BV(SProjectSummary));
- // if (self.Area = areaZheJiang) then
- // sTemp := '项目类型'
- // else
- // sTemp := '建设性质';
- //
- // if PV('Newly') = '新建' then
- // FGCXX.AttributeAddUTF8(sTemp, '1')
- // else
- // FGCXX.AttributeAddUTF8(sTemp, '2');
- FGCXX.AttributeAddUTF8('项目类型', '1'); // 1 施工,2 养护。 我们是施工,不是养护,单机版这个软件做不了养护的。
- s := BV(SRoadLevel);
- if s = '一级公路' then
- FGCXX.AttributeAddUTF8('专业划分', '2')
- else if s = '二级公路' then
- FGCXX.AttributeAddUTF8('专业划分', '3')
- else if s = '三级公路' then
- FGCXX.AttributeAddUTF8('专业划分', '4')
- else if s = '四级公路' then
- FGCXX.AttributeAddUTF8('专业划分', '5')
- else
- FGCXX.AttributeAddUTF8('专业划分', '1'); // '高速公路'
- if (self.Area = areaZheJiang) then
- sTemp := '道路里程-公里'
- else
- sTemp := '道路里程';
- FGCXX.AttributeAddUTF8(sTemp, BV(SRoadLength));
- FGCXX.AttributeAddUTF8('设计单位', BV(SDesignUnit));
- FGCXX.AttributeAddUTF8('计税方式', '1');
- if FFileType = xftZB then
- FGCXX.AttributeAddUTF8('文件类型', '1')
- else if FFileType = xftKZJ then
- FGCXX.AttributeAddUTF8('文件类型', '2')
- else if FFileType = xftTB then
- FGCXX.AttributeAddUTF8('文件类型', '3');
- if (self.Area = areaZheJiang) then
- begin
- // 数据校验码:通过【投标信息】和【公路工程汇总】下的所有字段内容计算哈希值。这里超前取值,先占坑,后续覆盖。
- FGCXX.AttributeAddUTF8('数据校验码', 'AAAAA');
- // 软件校验码:后续通过工具获取,这里先占坑,后续覆盖。
- FGCXX.AttributeAddUTF8('软件校验码', 'AAAAA');
- end;
- FGCXX.AttributeAddUTF8('标准版本号', '1.0');
- FGCXX.AttributeAddUTF8('GUID', GetProjectGUID(True)); // 这是建设项目的GUID码
- end;
- procedure TZTBXMLPort.AddZTBXX;
- var vChild: TXmlNode;
- DogNo: string;
- begin
- AddProgressForm(10, '正在生成招投标信息...');
- FZTBXX := FRoot.NodeNewUTF8('招投标信息');
- if FFileType = xftZB then
- vChild := FZTBXX.NodeNewUTF8('招标信息')
- else if FFileType = xftKZJ then
- vChild := FZTBXX.NodeNewUTF8('招标控制价')
- else if FFileType = xftTB then
- vChild := FZTBXX.NodeNewUTF8('投标信息');
- if (self.Area = areaZheJiang) then
- begin
- if (FFileType = xftZB) then
- begin
- vChild.AttributeAddUTF8('招标人', BV(SZhaoBiaoRen));
- vChild.AttributeAddUTF8('招标法定代表人或其授权人', BV(SZhaoBiaoRenRepresentative));
- vChild.AttributeAddUTF8('编制人', BV(SAuthor));
- vChild.AttributeAddUTF8('编制人资格证号', BV(SAuthorCertificate));
- vChild.AttributeAddUTF8('编制日期', Copy(BV(SEditDate), 1, 10));
- vChild.AttributeAddUTF8('招标代理机构', BV(SZhaoBiaoAgent));
- vChild.AttributeAddUTF8('招标范围', BV(SZhaoBiaoRange));
- vChild.AttributeAddUTF8('总工期日历天', BV(SZhaoBiaoCalendarDay));
- end
- else if (FFileType = xftTB) then
- begin
- DogNo := CLD_DogsBySerialNo;
- vChild.AttributeAddUTF8('投标人', BV(STouBiaoRen));
- vChild.AttributeAddUTF8('投标人法人或其授权人', BV(STouBiaoRenRepresentative));
- vChild.AttributeAddUTF8('投标人资质证号', BV(STouBiaoRenCertificate));
- vChild.AttributeAddUTF8('总工期日历天', BV(STouBiaoCalendarDay));
- vChild.AttributeAddUTF8('投标总价', FloatToStr(FAllProjectsTotalPriceSum)); // 此时还取不到,标段遍历完再修改此值
- vChild.AttributeAddUTF8('投标下浮率', BV(STouBiaoDownRate));
- vChild.AttributeAddUTF8('投标报价说明', BV(STouBiaoQuoteNote));
- vChild.AttributeAddUTF8('质量承诺', BV(STouBiaoQualityCommitment));
- vChild.AttributeAddUTF8('投标保证金', BV(STouBiaoDeposit));
- vChild.AttributeAddUTF8('项目经理或项目负责人', BV(STouBiaoProjectManager));
- vChild.AttributeAddUTF8('项目经理或项目负责人资格证号', BV(STouBiaoProjectManagerCertificate));
- vChild.AttributeAddUTF8('造价软件品牌', Application.Title);
- vChild.AttributeAddUTF8('造价软件版本', ScGetVersion);
- vChild.AttributeAddUTF8('造价软件加密锁编号', DogNo);
- vChild.AttributeAddUTF8('计算机硬件信息', Get_CPU_SN + Get_HDD_SN + Get_MAC_Address);
- vChild.AttributeAddUTF8('备注', '');
- end;
- end
- else
- begin
- if (FFileType = xftZB) or (FFileType = xftKZJ) then
- begin
- vChild.AttributeAddUTF8('招标人', BV('ZhaoBR'));
- vChild.AttributeAddUTF8('招标人纳税识别号', BV('ZhaoBRNSSBH'));
- vChild.AttributeAddUTF8('招标法定代表人或其授权人', BV('ZhaoBFR'));
- vChild.AttributeAddUTF8('招标法人或其授权人身份证号', BV('ZhaoBFRSFZH'));
- vChild.AttributeAddUTF8('造价咨询人', BV('ZaoJZXR'));
- vChild.AttributeAddUTF8('造价咨询人纳税识别号', BV('ZaoJZXRNSSBH'));
- vChild.AttributeAddUTF8('造价咨询人法定代表人或其授权人', BV('ZaoJZXFR'));
- vChild.AttributeAddUTF8('造价咨询法人或其授权人身份证号', BV('ZaoJZXFRSFZH'));
- end
- else if FFileType = xftTB then
- begin
- vChild.AttributeAddUTF8('投标人', BV('TouBR'));
- vChild.AttributeAddUTF8('投标人纳税识别号', BV('TouBRNSSBH'));
- vChild.AttributeAddUTF8('投标人法定代表或其授权人', BV('TouBFR'));
- vChild.AttributeAddUTF8('投标人法人或其授权人身份证号', BV('TouBFRSFZH'));
- end;
- vChild.AttributeAddUTF8('编制人', PD.Author);
- vChild.AttributeAddUTF8('编制人资格证号', PD.AuthorCertificate);
- vChild.AttributeAddUTF8('编制日期', Copy(DateToStr(PD.EditDate), 1, 10));
- vChild.AttributeAddUTF8('复核人', PD.Auditor);
- vChild.AttributeAddUTF8('复核人资格证号', PD.AuditorCertificate);
- vChild.AttributeAddUTF8('复核日期', Copy(DateToStr(PD.EditDate), 1, 10));
- if (FFileType = xftKZJ) or (FFileType = xftTB) then
- begin
- vChild.AttributeAddUTF8('审核人', BV('ShenHR'));
- vChild.AttributeAddUTF8('审核人资格证号', BV('ShenHRZGZH'));
- vChild.AttributeAddUTF8('审核日期', BV('ShenHRQ'));
- end;
- if FFileType = xftKZJ then
- begin
- vChild.AttributeAddUTF8('控制价总价', BV('KongZJZJ'));
- vChild.AttributeAddUTF8('工期', BV('GongQ'));
- vChild.AttributeAddUTF8('质量要求', BV('ZhiLYQ'));
- end;
- if FFileType = xftTB then
- begin
- vChild.AttributeAddUTF8('投标总价', FloatToStr(FAllProjectsTotalPriceSum));
- vChild.AttributeAddUTF8('工期', BV('GongQ'));
- vChild.AttributeAddUTF8('投标担保金额', BV('TouBDBJE'));
- vChild.AttributeAddUTF8('质量承诺', BV('ZhiLCN'));
- vChild.AttributeAddUTF8('投标担保方式', GetMapValue(GetMap('Map_TenderGuaranteeStyle'), BV('TouBDBFS')));
- vChild.AttributeAddUTF8('造价软件品牌', Application.Title);
- vChild.AttributeAddUTF8('造价软件版本', ScGetVersion);
- vChild.AttributeAddUTF8('造价软件加密锁编号', 'SCDOG001002');
- vChild.AttributeAddUTF8('计算机硬件信息', Get_CPU_SN + Get_HDD_SN + Get_MAC_Address);
- end;
- end;
- end;
- procedure TZTBXMLPort.AddGLGCHZMX;
- var n: Integer;
- vSL: TStringList;
- vGLGCHZMX: TXmlNode;
- begin
- vSL := TStringList.Create;
- try
- for n := 0 to FProjectInfoCacheList.Count - 1 do
- begin
- vSL.Delimiter := ';';
- vSL.DelimitedText := FProjectInfoCacheList[n];
- vGLGCHZMX := FGLGCHZ.NodeNewUTF8('公路工程汇总明细');
- vGLGCHZMX.AttributeAddUTF8('序号', vSL.Values['No']);
- vGLGCHZMX.AttributeAddUTF8('标段名称', vSL.Values['Name']);
- if (FFileType = xftZB) then
- vGLGCHZMX.AttributeAddUTF8('金额', '0')
- else
- vGLGCHZMX.AttributeAddUTF8('金额', vSL.Values['TotalPrice']);
- vGLGCHZMX.AttributeAddUTF8('唯一标识-Guid', vSL.Values['GUID']);
- vGLGCHZMX.AttributeAddUTF8('备注', '');
- end;
- finally
- vSL.Free;
- end;
- end;
- procedure TZTBXMLPort.AddGLGCSJ;
- begin
- FGLGCSJ := FRoot.NodeNewUTF8('公路工程数据');
- AddMultiProjects;
- FGLGCHZ := FGLGCSJ.NodeNewUTF8('公路工程汇总');
- if (self.Area = areaZheJiang) then
- begin
- FGLGCHZ := FGLGCHZ.NodeNewUTF8('公路工程汇总标题');
- end;
- AddGLGCHZMX;
- end;
- procedure TZTBXMLPort.AddGLBDGC(n: Integer);
- begin
- FGLBDGC := FGLGCSJ.NodeNewUTF8('公路标段工程');
- FGLBDGC.AttributeAddUTF8('序号', IntToStr(n + 1));
- FGLBDGC.AttributeAddUTF8('标段名称', ProjectManager.TenderName(PD.ID));
- if (FFileType = xftZB) then
- FGLBDGC.AttributeAddUTF8('金额', '0')
- else
- FGLBDGC.AttributeAddUTF8('金额', GetProjectTotalPrice);
- FGLBDGC.AttributeAddUTF8('唯一标识-Guid', GetProjectGUID);
- AddProgressForm(10, '正在导出工程量清单表...');
- FGCLQDB := FGLBDGC.NodeNewUTF8('工程量清单表');
- AddBillNodes;
- AddProgressForm(10, '正在导出计日工信息表...');
- FJRGXXB := FGLBDGC.NodeNewUTF8('计日工信息表');
- AddJRG;
- AddProgressForm(10, '正在导出造价汇总表...');
- AddZJHZMX;
- if (FFileType = xftZB) then
- FGLBDGC.NodeNewUTF8('人材机汇总')
- else
- begin
- AddProgressForm(10, '正在导出人材机汇总...');
- AddProjGLJs;
- end;
- end;
- procedure TZTBXMLPort.AddBillNodes;
- var vTree: TScBillsTree;
- begin
- vTree := TScProject(FProject).Bills.BillsTree;
- CalcBillsFees(vTree.Items[0]);
- RcsvAddBillNode(TScBillsItem(vTree.Items[0].FirstChild), FGCLQDB);
- end;
- procedure TZTBXMLPort.RcsvAddBillNode(AItem: TScBillsItem; AXMLParent: TXmlNode);
- var vBillNode, vBillMetNode: TXmlNode;
- procedure AddNodeMX; // 导出
- var qdzjCode, sCode, sGUID, sDataType: string;
- begin
- vBillNode := AXMLParent.NodeNewUTF8('工程量清单明细');
- vBillNode.AttributeAddUTF8('序号', Rec(AItem, 'SerialNo'));
- if Self.FileType = xftZB then
- sGUID := IDtoGUID(AItem.ID) // 招标要自己造GUID
- else
- sGUID := Rec(AItem, 'GUIDstr'); // 投标要直接读
- vBillNode.AttributeAddUTF8('GUID', sGUID);
- qdzjCode := GetZJ(AItem.FullCode, AItem.Name);
- sCode := AItem.Code;
- if sCode = '' then
- begin
- sCode := qdzjCode;
- end;
- vBillNode.AttributeAddUTF8('清单章节', qdzjCode);
- vBillNode.AttributeAddUTF8('子目长编号', sCode); // 子目长编号=子目号
- vBillNode.AttributeAddUTF8('子目号', sCode);
- vBillNode.AttributeAddUTF8('子目名称', AItem.Name);
- vBillNode.AttributeAddUTF8('单位', Rec(AItem, 'Units'));
- vBillNode.AttributeAddUTF8('数量', CheckNull(Rec(AItem, 'Quantity')));
- if (FFileType = xftZB) then
- begin
- if AItem.Rec.IsSpecialInterim.AsBoolean = True then // 21特殊,招标也要导出单价、合价。
- begin
- vBillNode.AttributeAddUTF8('单价', CheckNull(Rec(AItem, 'UnitPrice')));
- vBillNode.AttributeAddUTF8('合价', CheckNull(Rec(AItem, 'TotalPrice')));
- end
- else
- begin
- vBillNode.AttributeAddUTF8('单价', '0');
- vBillNode.AttributeAddUTF8('合价', '0');
- end;
- vBillNode.AttributeAddUTF8('备注', '');
- if AItem.Rec.IsSpecialInterim.AsBoolean = True then
- sDataType := '21' // 专项暂定
- else
- begin
- if AItem.IsLeaf then
- begin
- if SameText(AItem.Code, '102-3') then sDataType := '22' // 安全生产费
- else if SameText(AItem.Code, '101-1-1') then sDataType := '23' // 工程一切险
- else if SameText(AItem.Code, '101-1-2') then sDataType := '24' // 第三者责任险
- else if Pos('意外伤害险', AItem.Name) > 0 then sDataType := '25'
- else if Pos('工伤保险', AItem.Name) > 0 then sDataType := '26'
- else if Pos('其它保险', AItem.Name) > 0 then sDataType := '27'
- else sDataType := '20';
- end
- else
- sDataType := '1'; // 父清单
- end;
- vBillNode.AttributeAddUTF8('数据类型', sDataType);
- end
- else // 投标
- begin
- vBillNode.AttributeAddUTF8('单价', CheckNull(Rec(AItem, 'UnitPrice')));
- vBillNode.AttributeAddUTF8('合价', CheckNull(Rec(AItem, 'TotalPrice')));
- vBillNode.AttributeAddUTF8('备注', Rec(AItem, 'MemoStr'));
- vBillNode.AttributeAddUTF8('数据类型', Rec(AItem, 'DataType'));
- end;
- vBillNode.AttributeAddUTF8('人工费', FloatToStr(AItem.LabourFee));
- if (self.Area = areaZheJiang) then
- begin
- vBillNode.AttributeAddUTF8('人工单价', '0');
- vBillNode.AttributeAddUTF8('人工消耗量', '0');
- end;
- vBillNode.AttributeAddUTF8('主材费', FloatToStr(AItem.MaterialFee));
- vBillNode.AttributeAddUTF8('辅材费', '0');
- vBillNode.AttributeAddUTF8('设备费', '0');
- vBillNode.AttributeAddUTF8('机械使用费', FloatToStr(AItem.MachineFee));
- vBillNode.AttributeAddUTF8('措施费1', FloatToStr(AItem.OtherFee1));
- vBillNode.AttributeAddUTF8('措施费2', FloatToStr(AItem.OtherFee2));
- vBillNode.AttributeAddUTF8('企业管理费', FloatToStr(AItem.ManageFee));
- vBillNode.AttributeAddUTF8('规费', FloatToStr(AItem.LocaleFee));
- vBillNode.AttributeAddUTF8('利润', FloatToStr(AItem.Profit));
- vBillNode.AttributeAddUTF8('税金', FloatToStr(AItem.Tax));
- vBillNode.AttributeAddUTF8('评审清单', '0');
- if (AItem.IsLeaf and AItem.HasRations and (FFileType <> xftZB)) then
- begin
- if (self.Area = areaZheJiang) then
- begin
- vBillMetNode := vBillNode.NodeNewUTF8('清单主材表');
- AddBillMaterials(AItem, vBillMetNode);
- end;
- AddRationNodes(AItem, vBillNode);
- end;
- end;
- begin
- if AItem = nil then Exit;
- AddNodeMX;
- RcsvAddBillNode(TScBillsItem(AItem.FirstChild), vBillNode);
- RcsvAddBillNode(TScBillsItem(AItem.NextSibling), AXMLParent);
- end;
- procedure TZTBXMLPort.AddRationNodes(ABillItem: TScBillsItem; ABillNode: TXmlNode);
- var vRationNode: TXmlNode;
- // 定额工料机
- procedure AddRationGLJs(ARationID: Integer; ARationNode: TXmlNode);
- var vGLJNode: TXmlNode;
- sName: string;
- begin
- FQuery3.Close;
- FQuery3.SQL.Clear;
- FQuery3.SQL.Add(Format('SELECT * FROM GLJList WHERE RationID = %d', [ARationID]));
- FQuery3.Open;
- if FQuery3.RecordCount > 0 then
- begin
- if Self.Area = areaZheJiang then
- sName := '人材机编号'
- else
- sName := '人材机标识';
- FQuery3.First;
- while not FQuery3.Eof do
- begin
- vGLJNode := ARationNode.NodeNewUTF8('定额人材机含量明细');
- vGLJNode.AttributeAddUTF8(sName, FQuery3.FieldByName('GLJID').asString);
- vGLJNode.AttributeAddUTF8('人材机含量', FQuery3.FieldByName('Quantity').asString);
- FQuery3.Next;
- end;
- end;
- FQuery3.Close;
- end;
- // 数据类型
- function GetDataType: Integer;
- begin
- // (1=材料暂定;2=设备暂定;3=普通定额;4=不取费定额)
- // 旧:若清单的专项暂定是材料,则该清单下的定额的数据类型的值全取1;若是工程设备,则取2;其他情况取3。
- // 新:
- Result := 3;
- // if ABillItem.Rec.IsSpecialInterim.AsBoolean = True then
- // iDataType := ABillItem.Rec.InterimType.AsInteger;
- if FQuery2.FieldByName('CountPriceType').AsInteger = 2 then // 量价窗口添加的量价(直接手工录入添加、弹窗选择添加)
- begin
- if FQuery2.FieldByName('GLJMode').AsInteger <> 1 then // 量价窗口添加的量价(直接手工录入添加)
- Result := 4
- else // 量价窗口添加的量价(弹窗选择添加)
- Result := 1
- end
- else if FQuery2.FieldByName('CountPriceType').AsInteger = 3 then // 设备窗口添加的设备(直接手工录入添加、弹窗选择添加)
- Result := 2;
- end;
- var upFieldName: string;
- function V(AFieldName: string): string;
- begin
- Result := CheckNull(FQuery2.FieldByName(AFieldName).asString);
- end;
- begin
- FQuery2.Close;
- FQuery2.SQL.Clear;
- FQuery2.SQL.Add(Format('SELECT * FROM RationCalcList WHERE BillsItemID = %d Order by SerialNo', [ABillItem.ID]));
- FQuery2.Open;
- if FQuery2.RecordCount > 0 then
- begin
- FQuery2.First;
- while not FQuery2.Eof do
- begin
- vRationNode := ABillNode.NodeNewUTF8('定额信息表');
- vRationNode.AttributeAddUTF8('序号', V('SerialNo'));
- if (self.Area = areaZheJiang) then
- begin
- vRationNode.AttributeAddUTF8('GUID', IDtoGUID(FQuery2.FieldByName('ID').asInteger));
- end;
- vRationNode.AttributeAddUTF8('定额编号', FQuery2.FieldByName('Code').asString);
- vRationNode.AttributeAddUTF8('定额名称', FQuery2.FieldByName('Name').asString);
- vRationNode.AttributeAddUTF8('单位', CheckNull(FQuery2.FieldByName('Unit').asString, '-'));
- vRationNode.AttributeAddUTF8('数量', V('Quantity'));
- if FQuery2.FieldByName('Type').AsInteger = 1 then
- upFieldName := 'UnitDirectFee'
- else
- upFieldName := 'BuildingUnitPrice';
- vRationNode.AttributeAddUTF8('单价',V(upFieldName));
- vRationNode.AttributeAddUTF8('合价', V('BuildingFee'));
- vRationNode.AttributeAddUTF8('备注', '');
- vRationNode.AttributeAddUTF8('数据类型', IntToStr(GetDataType));
- vRationNode.AttributeAddUTF8('人工费', V('LabourFee'));
- vRationNode.AttributeAddUTF8('主材费', V('MaterialFee'));
- vRationNode.AttributeAddUTF8('辅材费', '0');
- vRationNode.AttributeAddUTF8('机械使用费', V('MachineFee'));
- vRationNode.AttributeAddUTF8('设备费', '0');
- vRationNode.AttributeAddUTF8('措施费1', V('OtherFee1'));
- vRationNode.AttributeAddUTF8('措施费2', V('OtherFee2'));
- vRationNode.AttributeAddUTF8('企业管理费', V('ManageFee'));
- vRationNode.AttributeAddUTF8('规费', V('LocaleFee'));
- vRationNode.AttributeAddUTF8('利润', V('Profit'));
- vRationNode.AttributeAddUTF8('税金', V('Tax'));
- AddRationGLJs(FQuery2.FieldByName('ID').AsInteger, vRationNode);
- FQuery2.Next;
- end;
- end;
- FQuery2.Close;
- end;
- procedure TZTBXMLPort.AddBillMaterials(ABillItem: TScBillsItem; ABillMetNode: TXmlNode);
- var billMetMX: TXmlNode;
- i: Integer;
- sSQL: string;
- begin
- sSQL := 'select Code, Name, Unit, BudgetPrice, Sum(Q) as Quantity, Format(Quantity * BudgetPrice, ''0.00'') AS HJ From (' +
- 'SELECT P.Code, P.name, P.Unit, G.Quantity as Q, P.BudgetPrice FROM ProjectGLJ AS P ' +
- 'LEFT JOIN GLJList AS G ON G.GLJID=P.ID ' +
- 'WHERE P.Type=4 AND G.BillsItemID=' + IntToStr(ABillItem.ID) +
- ') Group by Code, Name, Unit, BudgetPrice';
- // ') Group by Code, Name, Unit, BudgetPrice ORDER by Code';
- FQuery2.Close;
- FQuery2.SQL.Clear;
- FQuery2.SQL.Add(sSQL);
- FQuery2.Open;
- if FQuery2.RecordCount > 0 then
- begin
- i := 0;
- FQuery2.First;
- while not FQuery2.Eof do
- begin
- Inc(i);
- billMetMX := ABillMetNode.NodeNewUTF8('清单主材明细');
- billMetMX.AttributeAddUTF8('序号', IntToStr(i));
- billMetMX.AttributeAddUTF8('材料编码', FQuery2.FieldByName('Code').asString);
- billMetMX.AttributeAddUTF8('主材名称', FQuery2.FieldByName('Name').asString);
- billMetMX.AttributeAddUTF8('单位', FQuery2.FieldByName('Unit').asString);
- billMetMX.AttributeAddUTF8('主材消耗量', FQuery2.FieldByName('Quantity').asString);
- billMetMX.AttributeAddUTF8('单价', FQuery2.FieldByName('BudgetPrice').asString);
- billMetMX.AttributeAddUTF8('合价', FQuery2.FieldByName('HJ').asString);
- billMetMX.AttributeAddUTF8('备注', '');
- FQuery2.Next;
- end;
- end;
- FQuery2.Close;
- end;
- { // 添加计日工:接口是死的,这里写成活的,但难处理,留着备用,以防需求变更。
- procedure TahXMLPort.AddJRG;
- var vBill: TScBillsItem;
- procedure RcsvJRG(ABill: TScBillsItem; AXMLParent: IXMLNode);
- var vXMLNode: IXMLNode;
- begin
- if ABill = nil then Exit;
- if ABill.IsLeaf then
- begin
- vXMLNode := AXMLParent.NodeNew('计日工信息明细');
- vXMLNode.AttributeAdd('编号', ABill.Code;
- vXMLNode.AttributeAdd('名称', ABill.Name;
- vXMLNode.AttributeAdd('数据类型', StrToInt(AXMLParent.AttributeAdd('数据类型']) + 3;
- vXMLNode.AttributeAdd('单位', Rec(ABill, 'Unit');
- vXMLNode.AttributeAdd('暂定数量', '0';
- vXMLNode.AttributeAdd('单价', Rec(ABill, 'Unit');
- vXMLNode.AttributeAdd('合价', Rec(ABill, 'Unit');
- end
- else
- begin
- vXMLNode := AXMLParent.NodeNew('计日工信息标题');
- vXMLNode.AttributeAdd('序号', Rec(ABill, 'SerialNo');
- vXMLNode.AttributeAdd('名称', ABill.Name;
- if Pos('劳务', ABill.Name) > 0 then
- vXMLNode.AttributeAdd('数据类型', '1'
- else if Pos('材料', ABill.Name) > 0 then
- vXMLNode.AttributeAdd('数据类型', '2'
- else if Pos('机械', ABill.Name) > 0 then
- vXMLNode.AttributeAdd('数据类型', '3';
- vXMLNode.AttributeAdd('合价', Rec(ABill, 'TotalPrice');
- end;
- RcsvJRG(TScBillsItem(ABill.FirstChild), vXMLNode);
- RcsvJRG(TScBillsItem(ABill.NextSibling), AXMLParent);
- end;
- begin
- vBill := BillNode(idDayWork);
- RcsvJRG(TScBillsItem(vBill.FirstChild), FJRGXXB);
- end; }
- // 添加计日工:接口是死的,写成活的难处理,这里也跟着写死。
- procedure TZTBXMLPort.AddJRG;
- var vJRG, vKind, vChild: TScBillsItem;
- i, j: Integer;
- vJRGNode, vKindNode, vChildNode: TXmlNode;
- begin
- vJRG := BillNode(idDayWork);
- vJRGNode := FJRGXXB.NodeNewUTF8('计日工信息标题');
- vJRGNode.AttributeAddUTF8('序号', Rec(vJRG, 'SerialNo'));
- vJRGNode.AttributeAddUTF8('名称', vJRG.Name);
- vJRGNode.AttributeAddUTF8('数据类型', '0');
- if (FFileType = xftZB) then
- vJRGNode.AttributeAddUTF8('合价', '0')
- else
- vJRGNode.AttributeAddUTF8('合价', Rec(vJRG, 'TotalPrice'));
- for i := 0 to vJRG.ChildCount - 1 do
- begin
- vKind := TScBillsItem(vJRG.ChildNodes[i]);
- vKindNode := FJRGXXB.NodeNewUTF8('计日工信息标题');
- vKindNode.AttributeAddUTF8('序号', Rec(vKind, 'SerialNo'));
- vKindNode.AttributeAddUTF8('名称', vKind.Name);
- if Pos('劳务', vKind.Name) > 0 then
- vKindNode.AttributeAddUTF8('数据类型', '1')
- else if Pos('材料', vKind.Name) > 0 then
- vKindNode.AttributeAddUTF8('数据类型', '2')
- else if Pos('机械', vKind.Name) > 0 then
- vKindNode.AttributeAddUTF8('数据类型', '3');
- if (FFileType = xftZB) then
- vKindNode.AttributeAddUTF8('合价', '0')
- else
- vKindNode.AttributeAddUTF8('合价', Rec(vKind, 'TotalPrice'));
- for j := 0 to vKind.ChildCount - 1 do
- begin
- vChild := TScBillsItem(vKind.ChildNodes[j]);
- vChildNode := vKindNode.NodeNewUTF8('计日工信息明细');
- vChildNode.AttributeAddUTF8('编号', vChild.Code);
- vChildNode.AttributeAddUTF8('名称', vChild.Name);
- vChildNode.AttributeAddUTF8('数据类型', IntToStr(StrToInt(vKindNode.AttributeValueByNameUTF8['数据类型']) + 3));
- vChildNode.AttributeAddUTF8('单位', Rec(vChild, 'Units'));
- vChildNode.AttributeAddUTF8('暂定数量', Rec(vChild, 'Quantity'));
- if (FFileType = xftZB) then
- begin
- vChildNode.AttributeAddUTF8('单价', '0');
- vChildNode.AttributeAddUTF8('合价', '0');
- end
- else
- begin
- vChildNode.AttributeAddUTF8('单价', Rec(vChild, 'UnitPrice'));
- vChildNode.AttributeAddUTF8('合价', Rec(vChild, 'TotalPrice'));
- end;
- end;
- end;
- end;
- procedure TZTBXMLPort.AddZJHZMX;
- var sSQL, sZC, sLB: string;
- vZJHZB, vZJHZMX: TXmlNode;
- n: Integer;
- begin
- vZJHZB := FGLBDGC.NodeNewUTF8('造价汇总表');
- sSQL :=
- 'select ID, SerialNo, Name, TotalPrice, MemoStr ' +
- 'from Bills where (ParentID = -1) or (ParentID = 1) order by ParentID, SerialNo';
- FQuery1.Close;
- FQuery1.SQL.Text := sSQL;
- FQuery1.Open;
- FQuery1.First;
- n := 0;
- while not FQuery1.Eof do
- begin
- vZJHZMX := vZJHZB.NodeNewUTF8('造价汇总明细');
- GetZCLB(FQuery1.FieldByName('Name').AsString, sZC, sLB);
- if (self.Area = areaZheJiang) then
- begin
- if (sZC <> '') then
- sLB := sZC;
- end;
- Inc(n);
- vZJHZMX.AttributeAddUTF8('序号', IntToStr(n));
- vZJHZMX.AttributeAddUTF8('章次', sZC);
- vZJHZMX.AttributeAddUTF8('名称', FQuery1.FieldByName('Name').AsString);
- if (FFileType = xftZB) and (not (FQuery1.FieldByName('ID').AsInteger in [idSpecialInterimSum, idReserve])) then
- vZJHZMX.AttributeAddUTF8('金额', '0')
- else
- vZJHZMX.AttributeAddUTF8('金额', FloatToStr(ScRoundTo(FQuery1.FieldByName('TotalPrice').AsFloat, -2)));
- vZJHZMX.AttributeAddUTF8('类别', sLB);
- vZJHZMX.AttributeAddUTF8('备注', FQuery1.FieldByName('MemoStr').AsString);
- FQuery1.Next;
- end;
- FQuery1.Close;
- end;
- {-------------------------------------------------------------------------------
- 项目工料机:
- 纵横:1=人工 2=混凝土 4=材料 6=设备 8=机械 9=定额基价
- 池州:1=人工 2=材料 3=机械 4=设备 5=配比 6=机械台班 7=主材
- 规则不同,所以需要转换。【Provider】0=乙供;1=甲供
- BudgetPrice有太长的小数尾巴,即使Round(BudgetPrice, 2)也去不掉。
- 用Round(BudgetPrice * 1, 2)搞定。
- -------------------------------------------------------------------------------}
- procedure TZTBXMLPort.AddProjGLJs;
- var sSQL: string;
- begin
- if (self.Area = areaZheJiang) then
- begin
- sSQL :=
- 'Select Code as 人材机编号, Name as 人材机名称, Specs as 规格型号, Unit as 单位, ' +
- 'Round(Amount, 2) as 数量, Round(BudgetPrice * 1, 2) as 单价, ' +
- 'Switch(Type=2,''5'', Type=4, ''2'', Type=6, ''4'', Type=8, ''6'', True, Type) as 人材机类别, ' +
- 'IIF(Main=True, 1, 0) as 是否主要材料, ''0'' as 是否甲供, Remark as 备注 ' +
- 'from ProjectGLJ where Type<>9';
- end
- else
- begin
- sSQL :=
- 'Select ID as 人材机标识, Code as 人材机编号, Name as 人材机名称, Specs as 规格型号, Unit as 单位, ' +
- 'Round(Amount, 2) as 数量, Round(BudgetPrice * 1, 2) as 单价, ' +
- 'Switch(Type=2,''5'', Type=4, ''2'', Type=6, ''4'', Type=8, ''6'', True, Type) as 人材机类别, ' +
- 'IIF(Main=True, 1, 0) as 是否主要材料, ''0'' as 是否甲供, ''0'' as 是否暂估, Remark as 备注 ' +
- 'from ProjectGLJ where Type<>9';
- end;
- AddTabToXML(FQuery1, sSQL, FGLBDGC, '人材机汇总', '人材机汇总明细表');
- end;
- procedure TZTBXMLPort.GetZCLB(ABillName: string; var ACapter, AType: string);
- const
- // 这里取最小关键字,用于匹配清单名称的变化。
- G_Names: array [0..12, 0..2] of string = (
- ('第100章至700章清单', '', '1'),
- ('已包含在清单合计中的材料', '', '2'),
- ('清单合计减去材料', '', '3'),
- ('计日工合计', '', '4'),
- ('暂列金额', '', '5'),
- ('投标报价', '', '6'),
- ('第100章 ', '100', '11'), // 我们软件"章"字后面有2个空格!
- ('第200章 ', '200', '12'),
- ('第300章 ', '300', '13'),
- ('第400章 ', '400', '14'),
- ('第500章 ', '500', '15'),
- ('第600章 ', '600', '16'),
- ('第700章 ', '700', '17'));
- var i, j: Integer;
- begin
- {------------------灵异事件:------------------------------------------------
- for i := Low(G_Names) to High(G_Names) do 这句的 i 永远从 13 开始,递减到 1 结束。
- ①换成下面两句依然不行:
- for I := 0 to Length(G_Names) - 1 do
- for i := 0 to 12 do
- ②将二维数组换成3个常量数组,问题依旧:
- G_Names: array [0..12] of string = ('第100章至第700章','已包含在...', ...);
- G_Capters: array [0..12] of string = ('1', '', ...);
- G_Types: array [0..12] of string = ('1', '2', ...);
- ③ 将以上常量数组移到方法外面问题依旧。
- ④ 改变数组类型,问题依旧: G_Names: array [0..12] of ShortString、WideString。
- ⑤将该方法从Procedure换成function,问题依旧。
- 最后,在循环体内加上一句 MessageHint(IntToStr(i)); 问题消失! i 终于从 0 开始了!
- 所以,下面加个变量 j 转接一下 i 以解决该问题,虽然看上去比较奇怪...
- -----------------------------------------------------------------------------}
- for i := Low(G_Names) to High(G_Names) do
- begin
- if Pos(G_Names[i, 0], ABillName) > 0 then
- begin
- // MessageHint(IntToStr(i));
- j := i + 1;
- ACapter := G_Names[j - 1, 1];
- AType := G_Names[j - 1, 2];
- Break;
- end;
- end;
- end;
- // 通过【投标信息】和【公路工程汇总】下的所有字段内容计算哈希值。
- function TZTBXMLPort.GetDataCheckCode: string;
- var s: string;
- vNode: TXmlNode;
- i, n: Integer;
- begin
- s := '';
- vNode := FZTBXX.Elements[0]; // <投标信息>
- for i := 0 to vNode.AttributeCount - 1 do
- begin
- s := s + Utf8ToAnsi(vNode.AttributeValue[i]);
- end;
- for n := 0 to FGLGCHZ.ElementCount - 1 do
- begin
- vNode := FGLGCHZ.Elements[n]; // <公路工程汇总明细>
- for i := 0 to vNode.AttributeCount - 1 do
- begin
- s := s + Utf8ToAnsi(vNode.AttributeValue[i]);
- end;
- end;
- s := EncryptStringByMD5(s);
- Result := s;
- end;
- {TkmXMLPort}
- procedure TkmXMLPort.AddBQTable;
- var vBillTabNode, vBillItem, vBQPANode, vBQTitle: TXmlNode;
- j: Integer;
- sUnit, sZJ, sJ: string;
- procedure AddBQTitle;
- begin
- vBQTitle := vBillTabNode.NodeNewUTF8('BQTitle');
- vBQTitle.AttributeAddUTF8('BQTitleID', FQuery1.FieldByName('BQItemID').AsString);
- vBQTitle.AttributeAddUTF8('Name', FQuery1.FieldByName('Name').AsString);
- vBQTitle.AttributeAddUTF8('Remark', FQuery1.FieldByName('Remark').AsString);
- vBQTitle.AttributeAddUTF8('Sequence', FQuery1.FieldByName('Sequence').AsString);
- sZJ := GetZJByName(vBQTitle.AttributeValueByNameUTF8['Name']);
- end;
- procedure AddBQItem;
- procedure AddExtendFields(ABillID: Integer);
- var k: Integer;
- begin
- FQuery2.Close;
- FQuery2.SQL.Clear;
- FQuery2.SQL.Text :=
- 'select Format(LaborRate1/b.Quantity,''0.00'') as LaborRate,' +
- 'Format(MaterialRate1/b.Quantity,''0.00'') as MaterialRate,' +
- 'Format(MachineRate1/b.Quantity,''0.00'') as MachineRate,' +
- 'Format(OtherRate1/b.Quantity,''0.00'') as OtherRate,' +
- 'Format(OverheadRate1/b.Quantity,''0.00'') as OverheadRate,' +
- 'Format(RegulateRate1/b.Quantity,''0.00'') as RegulateRate,' +
- 'Format(ProfitRate1/b.Quantity,''0.00'') as ProfitRate,' +
- 'Format(TaxRate1/b.Quantity,''0.00'') as TaxRate from ' +
- '(SELECT BillsItemID, Sum(TenderLabourFee) as LaborRate1,' +
- 'Sum(TenderMaterialFee) as MaterialRate1,' +
- 'Sum(TenderMachineFee) as MachineRate1, Sum(TenderOtherDirectFee) as OtherRate1,' +
- 'Sum(TenderManageFee) as OverheadRate1, Sum(TenderLocaleFee) as RegulateRate1,' +
- 'Sum(TenderProfit) as ProfitRate1, Sum(TenderTax) as TaxRate1 ' +
- 'from RationCalclist where BillsItemID=' +
- IntToStr(ABillID) + ' group by BillsItemID) as j,Bills as b ' +
- 'where j.BillsItemID=b.ID';
- FQuery2.Open;
- if FQuery2.RecordCount > 0 then
- begin
- for k := 0 to FQuery2.FieldCount - 1 do
- vBillItem.AttributeAddUTF8(FQuery2.Fields[k].FieldName, FQuery2.Fields[k].AsString);
- end;
- FQuery2.Close;
- end;
- var i: Integer;
- begin
- vBillItem := vBQTitle.NodeNewUTF8('BQItem');
- for i := 0 to FQuery1.FieldCount - 2 do
- begin
- if SameText(FQuery1.Fields[i].FieldName, 'Unit') then
- vBillItem.AttributeAddUTF8(FQuery1.Fields[i].FieldName, ChangeUnit_m3(FQuery1.Fields[i].AsString))
- else if SameText(FQuery1.Fields[i].FieldName, 'ZJID') then
- vBillItem.AttributeAddUTF8(FQuery1.Fields[i].FieldName, sZJ)
- else
- vBillItem.AttributeAddUTF8(FQuery1.Fields[i].FieldName, FQuery1.Fields[i].AsString);
- end;
- if (FQuery1.FieldByName('IsLeaf').AsBoolean = True) then
- begin
- AddProgressForm(0, FSubHint2 + ':规费利润税金等');
- AddExtendFields(StrToInt(vBillItem.AttributeValueByNameUTF8['BQItemID']));
- end;
- if (FFileType = xftTB) and (FQuery1.FieldByName('IsLeaf').AsBoolean = True) then
- begin
- AddProgressForm(0, FSubHint2 + ':定额、工料机');
- AddNorms(vBillItem);
- AddProgressForm(0, FSubHint2 + ':汇总分析');
- AddBQPriceAnalysisItem(vBillItem);
- end;
- end;
- begin
- vBillTabNode := FUPNode.NodeNewUTF8('BQTable');
- FQuery1.Close;
- FQuery1.SQL.Clear;
- FQuery1.SQL.Text :=
- 'Select ID as BQItemID, FullCode as Code, Name, ''100'' as ZJID, Units as Unit, Quantity, ' +
- 'TenderUnitPrice as Rate, TenderTotalPrice as Total, MemoStr as Remark, ' +
- 'SerialNo as Sequence, ''False'' as IsPriceCeiling, IsLeaf ' +
- 'from Bills where ID > 1 and SerialNo <= ' + IntToStr(FSN_BillsEnd) + ' order by SerialNo';
- FQuery1.Open;
- j := 0;
- FQuery1.First;
- while not FQuery1.Eof do
- begin
- if FQuery1.FieldByName('Code').AsString = '' then
- AddBQTitle
- else
- AddBQItem;
- Inc(j);
- sJ := '第 ' + IntToStr(j) + ' 条';
- FSubHint2 := FSubHint + sJ;
- AddProgressForm(0, FSubHint2);
- FQuery1.Next;
- end;
- FQuery1.Close;
- end;
- procedure TkmXMLPort.AddNorms(ARoot: TXmlNode); // 定额
- var sBillID: string;
- vRNode, vRItemNode: TXmlNode;
- i: Integer;
- begin
- sBillID := ARoot.AttributeValueByNameUTF8['BQItemID'];
- FQuery2.Close;
- FQuery2.SQL.Clear;
- FQuery2.SQL.Text := Format(
- 'Select ID as NormItemID, Code, Name, Unit, Quantity, ' +
- 'Format(TenderLabourFee/Quantity,''0.00'') as LaborRate, ' +
- 'Format(TenderMaterialFee/Quantity,''0.00'') as MaterialRate, ' +
- 'Format(TenderMachineFee/Quantity,''0.00'') as MachineRate, ' +
- 'Format(TenderManageFee/Quantity,''0.00'') as OverheadRate, ' +
- 'Format(TenderLocaleFee/Quantity,''0.00'') as RegulateRate,' +
- 'Format(TenderProfit/Quantity,''0.00'') as ProfitRate, ' +
- 'Format(TenderTax/Quantity,''0.00'') as TaxRate, ' +
- 'Format(TenderOtherDirectFee/Quantity,''0.00'') as OtherRate, ' +
- 'Format(TenderBuildingFee/Quantity,''0.00'') as Rate, ' +
- 'TenderBuildingFee as Total, '''' as Remark, ' +
- 'Code as StandardCode,' +
- '''%s'' as NormLibrary, %d as FeeFileID, ' +
- 'SerialNo as Sequence, ''False'' as IsPriceCeiling ' +
- 'from RationCalcList where BillsItemID = %s',
- [FRationLibCode, FFeeRateFile.Lib.ID, sBillID]);
- FQuery2.Open;
- if FQuery2.RecordCount = 0 then Exit;
- vRNode := ARoot.NodeNewUTF8('Norms');
-
- FQuery2.First;
- while not FQuery2.Eof do
- begin
- vRItemNode := vRNode.NodeNewUTF8('NormsItem');
- for i := 0 to FQuery2.FieldCount - 1 do
- begin
- if SameText(FQuery2.Fields[i].FieldName, 'Unit') then
- vRItemNode.AttributeAddUTF8(FQuery2.Fields[i].FieldName, ChangeUnit_m3(FQuery2.Fields[i].AsString))
- else
- vRItemNode.AttributeAddUTF8(FQuery2.Fields[i].FieldName, FQuery2.Fields[i].AsString);
- end;
- AddNormResUsageItem(vRItemNode);
- FQuery2.Next;
- end;
- FQuery2.Close;
- end;
- // 数量单价 云南接口中没有提到这个,暂时不用。
- procedure TkmXMLPort.AddQuantityUnitPrice(ARoot: TXmlNode);
- var sBillID, sSQL: string;
- begin
- sBillID := ARoot.AttributeValueByNameUTF8['BQItemID'];
- sSQL := Format(
- 'Select Name, Code, Unit, Quantity, ' +
- 'UnitDirectFee as Rate, BuildingFee as Total, ' +
- 'SerialNo as Sequence ' +
- 'from RationCalcList where BillsItemID = %s and Type=1', [sBillID]);
- AddTabToXML(FQuery2, sSQL, ARoot, '', 'QuantityUnitPriceItem');
- end;
- {-------------------------------------------------------------------------------
- 清单子目(所有定额)工料机汇总
- 对每条清单子目下的所有定额的工料机进行汇总,除以清单工程量
- -------------------------------------------------------------------------------}
- procedure TkmXMLPort.AddBQPriceAnalysisItem(ARoot: TXmlNode);
- var sBillID, sSQL: string;
- begin
- sBillID := ARoot.AttributeValueByNameUTF8['BQItemID'];
- sSQL := Format(
- 'select Code, Specs as XHGG, Name, Unit, Format(Qty2,''0.00'') as Quantity, ' +
- 'Format(TenderPrice,''0.00'') as Rate, ' +
- 'Format(Qty2*TenderPrice,''0.00'') as Total, Code as Sequence ' +
- 'from (select g.GLJID, g.Qty / b.Quantity as Qty2 from ' +
- '(select BillsItemID,GLJID, Sum(TenderQuantity*RationItemQuantity) as Qty ' +
- 'from GLJList where BillsItemID=%s and Code <> 1999 and Quantity <> 0 ' +
- 'Group by BillsItemID,GLJID) as g, Bills as b ' +
- 'where g.BillsItemID=b.ID) as j,ProjectGLJ as p ' +
- 'where j.GLJID=p.ID order by Code', [sBillID]);
- AddTabToXML(FQuery2, sSQL, ARoot, '', 'BQPriceAnalysisItem');
- end;
- procedure TkmXMLPort.AddNormResUsageItem(ARoot: TXmlNode);
- var sRID, sSQL: string;
- begin
- sRID := ARoot.AttributeValueByNameUTF8['NormItemID'];
- sSQL := Format(
- 'Select RGLJID as [ResourceID], Quantity as [Usage] ' +
- 'from GLJList where RationID = %s', [sRID]);
- AddTabToXML(FQuery3, sSQL, ARoot, '', 'NormResUsageItem');
- end;
- {-------------------------------------------------------------------------------
- 计日工:有树结构
- 201 水泥 0.000
- 201-1 32.5级水泥 t 280.000 270.79
- 201-2 42.5级水泥 t 125.000 625.77
- 201-3 52.5级水泥 t 75.000 60.28
- 筑龙:【CostKind】1 劳务 2 材料 3 施工机械
- 纵横:5 劳务 6 材料 7 施工机械
- --------------------------------------------------------------------------------}
- procedure TkmXMLPort.AddDayWorkTable;
- var sSQL, sCK: string;
- iSNFrom, iSNTo, iSN6, iSN7: Integer;
- vDWTab, vDWTitle, vDWItem: TXmlNode;
- procedure AddDayWorkTitle;
- begin
- vDWTitle := vDWTab.NodeNewUTF8('DayWorkTitle');
- vDWTitle.AttributeAddUTF8('DayWorkTitleID', FQuery1.FieldByName('DayWorkItemID').AsString);
- vDWTitle.AttributeAddUTF8('Code', FQuery1.FieldByName('Code').AsString);
- vDWTitle.AttributeAddUTF8('Name', FQuery1.FieldByName('Name').AsString);
- vDWTitle.AttributeAddUTF8('Total', FQuery1.FieldByName('Total').AsString);
- vDWTitle.AttributeAddUTF8('CostKind', FQuery1.FieldByName('CostKind').AsString);
- vDWTitle.AttributeAddUTF8('Remark', FQuery1.FieldByName('Remark').AsString);
- vDWTitle.AttributeAddUTF8('Sequence', FQuery1.FieldByName('Sequence').AsString);
- end;
- procedure AddDayWorkItem;
- var i: Integer;
- begin
- if FQuery1.FieldByName('ParentID').AsInteger in [5, 6, 7] then
- vDWItem := vDWTab.NodeNewUTF8('DayWorkItem')
- else
- vDWItem := vDWTitle.NodeNewUTF8('DayWorkItem');
- for i := 0 to FQuery1.FieldCount - 3 do
- begin
- if SameText(FQuery1.Fields[i].FieldName, 'Unit') then
- vDWItem.AttributeAddUTF8(FQuery1.Fields[i].FieldName, ChangeUnit_m3(FQuery1.Fields[i].AsString))
- else
- vDWItem.AttributeAddUTF8(FQuery1.Fields[i].FieldName, FQuery1.Fields[i].AsString);
- end;
- end;
- begin
- if TScProject(FProject).Bills.BillsTree[idDayWork].ChildCount = 0 then Exit;
- iSNFrom := IDtoSerialNo(idDayWorkLabour) + 1;
- if iSNFrom = 1 then Exit; // 缺少“劳务”
- iSN6 := IDtoSerialNo(idDayWorkMaterial);
- if iSN6 = 0 then Exit; // 缺少“材料”
- iSN7 := IDtoSerialNo(idDayWorkMachine);
- if iSN7 = 0 then Exit; // 缺少“机械”
- iSNTo := IDtoSerialNo(8) - 1;
- vDWTab := FUPNode.NodeNewUTF8('DayWorkTable');
- sCK := Format('Switch(SerialNo Between %d And %d, ''1'',' +
- 'SerialNo Between %d And %d, ''2'', SerialNo Between %d And %d, ''3''' +
- ') AS CostKind', [iSNFrom, iSN6, iSN6, iSN7, iSN7, iSNTo]);
- sSQL := Format(
- 'Select ID as DayWorkItemID, Code, Name, Units as Unit, Quantity, ' +
- 'TenderUnitPrice as Rate, TenderTotalPrice as Total, %s, ' +
- 'MemoStr as Remark, SerialNo as Sequence, IsLeaf, ParentID ' +
- 'from Bills where (SerialNo between %d and %d) and ' +
- '(ID not between %d and %d) order by SerialNo', [sCK, iSNFrom, iSNTo, 5, 7]);
- FQuery1.Close;
- FQuery1.SQL.Clear;
- FQuery1.SQL.Text := sSQL;
- FQuery1.Open;
- FQuery1.First;
- while not FQuery1.Eof do
- begin
- if FQuery1.FieldByName('IsLeaf').AsBoolean = False then
- AddDayWorkTitle
- else
- AddDayWorkItem;
- FQuery1.Next;
- end;
- FQuery1.Close;
- end;
- {-------------------------------------------------------------------------------
- 材料:单价文件GLJList表
- 纵横:1 人工 2 混凝土 3 材料 4 机械 5 定额基价
- 筑龙:1 人工 2 材料 3 机械台班
- -------------------------------------------------------------------------------}
- procedure TkmXMLPort.AddMaterialTable;
- var sSQL: string;
- vQry: TADOQuery;
- begin
- vQry := TADOQuery.Create(nil);
- try
- vQry.Connection := FUnitPriceFile.Lib.Connection;
- sSQL := 'Select Code as ItemID, Code, Name, Specs as Spec, Unit, ' +
- 'Price as Rate, Switch(Type=3,''2'',Type=4,''3'',true,Type) as CostKind, ' +
- ''''' as Remark, Code as Sequence From GLJList Order by Code';
- AddTabToXML(vQry, sSQL, FUPNode, 'MaterialTable', 'MaterialItem');
- finally
- vQry.Close;
- vQry.Free;
- end;
- end;
- {-------------------------------------------------------------------------------
- 项目工料机:
- 纵横:1=人工 2=混凝土 3=材料 4=机械
- 筑龙:1=人工 2=材料 3=机械 4=设备 5=主材
- 规则不同,所以需要转换。【Provider】0=乙供;1=甲供
- BudgetPrice有太长的小数尾巴,即使Round(BudgetPrice, 2)也去不掉。
- 用Round(BudgetPrice * 1, 2)搞定。
- -------------------------------------------------------------------------------}
- procedure TkmXMLPort.AddResource;
- var sSQL: string;
- begin
- sSQL :=
- 'Select ID as ResourceID, Code, Name, Specs as Spec, Unit,' +
- 'Round(TenderPrice * 1, 2) as Rate, Round(TenderAmount, 2) as Quantity, ' +
- 'Round(TenderPrice * TenderAmount, 2) as Total, '+
- 'Switch(Type=3 and Main=False,''9'', Type=3 and Main=True, ''2'', Type=4 and Main=True, ''3'', True, Type) as CostKind, ' +
- 'Remark, '''' as ProducingArea, '''' as Supplier, '+
- ''''' as Provider, Code as StandardCode, LibID as NormLibrary ' +
- 'from ProjectGLJ';
- AddTabToXML(FQuery1, sSQL, FUPNode, 'Resource', 'ResourceItem');
- end;
- procedure TkmXMLPort.AddMaterialProvisionalPriceTable;
- var sSQL: string;
- begin
- sSQL :=
- 'Select ID as ItemID, FullCode as Code, Name, Units as Unit, Quantity, TenderUnitPrice as Rate, ' +
- 'TenderTotalPrice as Total, MemoStr as Remark, SerialNo as Sequence ' +
- 'from Bills where InterimType=1';
- AddTabToXML(FQuery1, sSQL, FUPNode, 'MaterialProvisionalPriceTable', 'MaterialProvisionalPriceItem');
- end;
- procedure TkmXMLPort.AddProjEquipmentPriceTable;
- var sSQL: string;
- begin
- sSQL :=
- 'Select ID as ItemID, FullCode as Code, Name, Units as Unit, Quantity, TenderUnitPrice as Rate, ' +
- 'TenderTotalPrice as Total, MemoStr as Remark, SerialNo as Sequence ' +
- 'from Bills where InterimType=2';
- AddTabToXML(FQuery1, sSQL, FUPNode, 'ProjEquipmentPriceTable', 'ProjEquipmentPriceItem');
- end;
- procedure TkmXMLPort.AddProjProvisionalPriceTable;
- var sSQL: string;
- begin
- sSQL :=
- 'Select ID as ItemID, FullCode as Code, Name, '''' as Content, ' +
- 'TenderTotalPrice as Price, MemoStr as Remark, SerialNo as Sequence ' +
- 'from Bills where InterimType=3';
- AddTabToXML(FQuery1, sSQL, FUPNode, 'ProjProvisionalPriceTable', 'ProjProvisionalPriceItem');
- end;
- {-------------------------------------------------------------------------------
- 交通机电设施备品备件:
- 公路工程工程量清单计量规范2010-05-18,P27有这张表,表里面的数据从清单第1300章读取。
- 以上信息是王晶致电云南省交通运输厅工程造价管理局咨询的。
- -------------------------------------------------------------------------------}
- procedure TkmXMLPort.AddElectEquipmentTable;
- var vEETable, vNode: TXmlNode;
- i: Integer;
- begin
- vEETable := FUPNode.NodeNewUTF8('ElectEquipmentTable');
- FQuery1.Close;
- FQuery1.SQL.Clear;
- FQuery1.SQL.Text := Format(
- 'Select ID as ItemID, Name, '''' as Spec, Units as Unit, TenderUnitPrice as Rate, ' +
- 'Quantity, TenderTotalPrice as Total, ChapterID as CostKind, ' +
- 'MemoStr as Remark, SerialNo as Sequence ' +
- 'from Bills where (SerialNo >= %d) and (SerialNo < %d) and (IsLeaf=True) order by SerialNo',
- [FSN_EEBegin, FSN_ID2]);
- FQuery1.Open;
- FQuery1.First;
- while not FQuery1.Eof do
- begin
- vNode := vEETable.NodeNewUTF8('ElectEquipmentItem');
- for i := 0 to FQuery1.FieldCount - 1 do
- begin
- if SameText(FQuery1.Fields[i].FieldName, 'Unit') then
- vNode.AttributeAddUTF8(FQuery1.Fields[i].FieldName, ChangeUnit_m3(FQuery1.Fields[i].AsString))
- else if SameText(FQuery1.Fields[i].FieldName, 'CostKind') then
- vNode.AttributeAddUTF8(FQuery1.Fields[i].FieldName, GetEECostKind(FQuery1.Fields[i].AsInteger))
- else
- vNode.AttributeAddUTF8(FQuery1.Fields[i].FieldName, FQuery1.Fields[i].AsString);
- end;
- FQuery1.Next;
- end;
- FQuery1.Close;
- end;
- procedure TkmXMLPort.AddDetail;
- procedure AddTenderInfo;
- var vNode: TXmlNode;
- begin
- vNode := FRoot.NodeNewUTF8('TenderInfo');
- vNode.AttributeAddUTF8('Tenderer', '');
- vNode.AttributeAddUTF8('Total', '');
- vNode.AttributeAddUTF8('Duration', '');
- vNode.AttributeAddUTF8('NoncompetitiveCost', '');
- vNode.AttributeAddUTF8('Deposit', '');
- vNode.AttributeAddUTF8('SuretyKind', '');
- vNode.AttributeAddUTF8('QualityPromise', '');
- end;
- procedure AddProjectAddInfo;
- var vNode, vItem: TXmlNode;
- i: Integer;
- begin
- vNode := FRoot.NodeNewUTF8('ProjectAddInfo');
- end;
- procedure AddSingleProject;
- begin
- FSPNode := FRoot.NodeNewUTF8('SingleProject');
- FSPNode.AttributeAddUTF8('ProjectID', '0');
- FSPNode.AttributeAddUTF8('Code', '0');
- FSPNode.AttributeAddUTF8('Name', PD.BuildProjectName);
- FSPNode.AttributeAddUTF8('Total', '0');
- FSPNode.AttributeAddUTF8('Sequence', '0');
- end;
- procedure AddUnitProject;
- var
- iProjectID: Integer;
- strName: string;
- PropRec: TsdDataRecord;
- procedure GetProjInfo(AFileName: string);
- var
- Rec: TsdDataRecord;
- begin
- Rec := ProjectManager.TendersRec(AFileName);
- iProjectID := Rec.ValueByName('ID').AsInteger;
- strName := Rec.ValueByName('Name').AsString;
- end;
- function RecV(AField: string): string;
- begin
- Result := PropRec.ValueByName(AField).AsString;
- end;
- begin
- GetProjInfo(PD.FileName);
- PropRec := ProjectManager.PropertiesRec(iProjectID);
- if PropRec <> nil then
- begin
- FUPNode := FSPNode.NodeNewUTF8('UnitProject');
- FUPNode.AttributeAddUTF8('ProjectID', IntToStr(iProjectID));
- FUPNode.AttributeAddUTF8('Code', RecV('Value14'));
- FUPNode.AttributeAddUTF8('Name', strName);
- FUPNode.AttributeAddUTF8('BuildingArea', RecV('Value5'));
- FUPNode.AttributeAddUTF8('NoncompetitiveCost', '0');
- FUPNode.AttributeAddUTF8('Total', RecV('Value2'));
- FUPNode.AttributeAddUTF8('MarketPriceStandard', '');
- FUPNode.AttributeAddUTF8('NormLibrary', '0');
- FUPNode.AttributeAddUTF8('Sequence', '0');
- end
- else
- begin
- MessageWarning('操作失败:无法找到该标段的相关信息!');
- Abort;
- end;
- end;
- procedure AddFeeFileTable;
- var vNode: TXmlNode;
- begin
- vNode := FUPNode.NodeNewUTF8('FeeFileTable');
- vNode := vNode.NodeNewUTF8('FeeFileItem');
- vNode.AttributeAddUTF8('FeeFileID', IntToStr(FFeeRateFile.Lib.ID));
- vNode.AttributeAddUTF8('FeeFileName', ExtractFileName(FFeeRateFile.LibName));
- vNode.AttributeAddUTF8('NormLibrary', FRationLibCode);
- end;
- var sHint: string;
- iSN: Integer;
- cTP: Currency;
- begin
- if not Assigned(FFeeRateFile.Lib) then
- begin
- MessageWarning('操作失败:请先选择费率文件然后再导出!');
- Exit;
- end;
- if not Assigned(FUnitPriceFile.Lib) then
- begin
- MessageWarning('操作失败:请先选择单价文件然后再导出!');
- Exit;
- end;
- if FFileType = xftTB then
- sHint := '投标'
- else
- sHint := '招标';
- RefreshProgressForm(0, Format('正在导出%s文件:%s...', [sHint, '建设项目']));
- FSN_ID2 := IDtoSerialNo(2);
- cTP := 0;
- iSN := -1; // 这个必须!
- EEValue(iSN, cTP);
- FSN_EEBegin := iSN;
- FEETotalPrice := cTP;
- if FSN_EEBegin = -1 then
- FSN_BillsEnd := FSN_ID2 - 1
- else
- FSN_BillsEnd := FSN_EEBegin - 1;
- AddTenderInfo;
- AddProjectAddInfo;
- AddSingleProject;
- AddUnitProject;
- AddFeeFileTable;
- if FFileType = xftTB then
- AddSummary;
- FSubHint := Format('正在导出%s文件:%s...', [sHint, '清单']);
- AddProgressForm(10, FSubHint);
- AddBQTable;
- AddProgressForm(20, Format('正在导出%s文件:%s...', [sHint, '计日工']));
- AddDayWorkTable;
- AddProgressForm(10, Format('正在导出%s文件:%s...', [sHint, '材料暂估价']));
- AddMaterialProvisionalPriceTable;
- AddProgressForm(10, Format('正在导出%s文件:%s...', [sHint, '工程设备暂估价']));
- AddProjEquipmentPriceTable;
- AddProgressForm(10, Format('正在导出%s文件:%s...', [sHint, '专业工程暂估价']));
- AddProjProvisionalPriceTable;
- if FSN_EEBegin <> -1 then
- begin
- AddProgressForm(10, Format('正在导出%s文件:%s...', [sHint, '交通机电设施备品备件']));
- AddElectEquipmentTable;
- end;
- if FFileType = xftTB then
- begin
- AddProgressForm(10, Format('正在导出%s文件:%s...', [sHint, '工料机单价']));
- AddMaterialTable;
- AddProgressForm(10, Format('正在导出%s文件:%s...', [sHint, '项目工料机']));
- AddResource;
- end;
- end;
- constructor TkmXMLPort.Create;
- begin
- inherited;
- FRationLibCode := '0';
- end;
- procedure TkmXMLPort.AddSummary;
- var sSQL: string;
- vNode: TXmlNode;
- i: Integer;
- const SmyArr: array[1..7, 1..4] of string = (
- ('1', '工程量清单人工费', 'VZ_RGF', 'TenderLabourFee'),
- ('2', '工程量清单材料费', 'VZ_CLF', 'TenderMaterialFee'),
- ('3', '工程量清单机械费', 'VZ_JXF', 'TenderMachineFee'),
- ('4', '工程量清单管理费', 'VZ_GLF', 'TenderIndirectFee'),
- ('5', '工程量清单利润费', 'VZ_LR', 'TenderProfit'),
- ('6', '工程量清单税金', 'VZ_SJ', 'TenderTax'),
- ('7', '工程量清单其他费', 'VZ_QTF', 'TenderOtherDirectFee')
- );
- const SmyArr2: array[1..6, 1..4] of string = (
- ('8', '工程量清单合计', 'VZ_HJ', '1'),
- ('9', '计日工合计', 'LXXM_HJ', '4'),
- ('10', '暂估价合计', 'ZGJ_HJ', '2'),
- ('11', '交通机电设施备品备件合计', 'JTJD_HJ', '1'), // 这里的ID=1只是为了返回一条记录,可以是其它任意一个存在的值。
- ('12', '不可预见费合价', 'BKYJF_HJ', '8'),
- ('13', '总造价', 'VZ_ZZJ', '9')
- );
- begin
- vNode := FUPNode.NodeNewUTF8('Summary');
- for i := Low(SmyArr) to High(SmyArr) do
- begin
- sSQL :=
- Format(
- 'Select %d as CostID, %d as CostKind, ''%s'' as CostCode, ''%s'' as Name, ' +
- ''''' as CostBase, '''' as CostRate, Sum(%s) as Total, ' +
- '''%s'' as Remark, ''false'' as IsNoncompetitiveCost, %d as Sequence ' +
- 'from RationCalcList',[
- StrToInt(SmyArr[i, 1]), StrToInt(SmyArr[i, 1]), SmyArr[i, 1], SmyArr[i, 2],
- SmyArr[i, 4], SmyArr[i, 3], StrToInt(SmyArr[i, 1])
- ]);
- AddTabToXML(FQuery1, sSQL, vNode, '', 'SummaryItem');
- end;
- for i := Low(SmyArr2) to High(SmyArr2) do
- begin
- if i = 4 then
- begin
- sSQL := Format(
- 'Select %d as CostID, %d as CostKind, ''%s'' as CostCode, ''%s'' as Name, ' +
- ''''' as CostBase, '''' as CostRate, %f as Total, ' +
- '''%s'' as Remark, ''false'' as IsNoncompetitiveCost, %d as Sequence ' +
- 'from Bills where ID=%s',[
- StrToInt(SmyArr2[i, 1]), StrToInt(SmyArr2[i, 1]), SmyArr2[i, 1], SmyArr2[i, 2],
- FEETotalPrice , SmyArr2[i, 3], StrToInt(SmyArr2[i, 1]), SmyArr2[i, 4]
- ]);
- end
- else
- begin
- sSQL := Format(
- 'Select %d as CostID, %d as CostKind, ''%s'' as CostCode, ''%s'' as Name, ' +
- ''''' as CostBase, '''' as CostRate, Sum(TenderTotalPrice) as Total, ' +
- '''%s'' as Remark, ''false'' as IsNoncompetitiveCost, %d as Sequence ' +
- 'from Bills where ID=%s',[
- StrToInt(SmyArr2[i, 1]), StrToInt(SmyArr2[i, 1]), SmyArr2[i, 1], SmyArr2[i, 2],
- SmyArr2[i, 3], StrToInt(SmyArr2[i, 1]), SmyArr2[i, 4]
- ]);
- end;
- AddTabToXML(FQuery1, sSQL, vNode, '', 'SummaryItem');
- end;
- end;
- procedure TkmXMLPort.EEValue(var ABeginSN: Integer; var ATotalPrice: Currency);
- var vRoot, vNode: TScBillsItem;
- i: Integer;
- begin
- with TScProject(FProject).Bills do
- begin
- vRoot := BillsTree.BillsItem[1];
- for i := 0 to vRoot.ChildCount - 1 do
- begin
- vNode := TScBillsItem(vRoot.ChildNodes[i]);
- if (vNode.Code = '') and (Pos('清单 第', vNode.Name) > 0) then
- begin
- if (Pos('900', vNode.Name) > 0) or (Pos('1000', vNode.Name) > 0)
- or (Pos('1100', vNode.Name) > 0) or (Pos('1200', vNode.Name) > 0)
- or (Pos('1300', vNode.Name) > 0) then
- begin
- ABeginSN := IDtoSerialNo(vNode.ID);
- Break;
- end;
- end;
- end;
- if ABeginSN <> -1 then // 找到了
- begin
- FQuery1.Close;
- FQuery1.SQL.Text := Format('Select Sum(TenderTotalPrice) as TP from Bills ' +
- 'where ParentID=%d and SerialNo >= %d', [1, ABeginSN]);
- FQuery1.Open;
- ATotalPrice := FQuery1.FieldByName('TP').AsCurrency;
- FQuery1.Close;
- end;
- end;
- end;
- function TkmXMLPort.GetEECostKind(AChapterID: Integer): string;
- var strName, sZJ, sSQL: string;
- begin
- sSQL := Format('Select Name from Bills where ID = %d', [AChapterID]);
- strName := DoSearch(sSQL, 'Name');
- sZJ := GetZJByName(strName);
- if sZJ = '900' then
- Result := '1'
- else if sZJ = '1000' then
- Result := '2'
- else if sZJ = '1100' then
- Result := '3'
- else if sZJ = '1200' then
- Result := '4'
- else if sZJ = '1300' then
- Result := '5';
- end;
- procedure TkmXMLPort.LoadFromXML;
- var vNode, vSingleProject, vUnitProject, vBQTable, vBQTitle, vBQItem: TXmlNode;
- i: Integer;
- vItem: TScBillsItem;
- { 筑龙XML格式
- <BQTitle BQTitleID="216" Name="清单 第100章 总则" Remark="" Sequence="1">
- <BQItem BQItemID="217" Code="101" Name="通则" ZJID="100" Unit="" Quantity="0" Rate="0" Total="1100" Remark="" Sequence="2" IsPriceCeiling="False"/>
- <BQItem BQItemID="218" Code="101-1" Name="保险费" ZJID="100" Unit="" Quantity="0" Rate="0" Total="1100" Remark="" Sequence="3" IsPriceCeiling="False"/>
- <BQItem BQItemID="219" Code="101-1-1" Name="按合同条款规定,提供建筑工程一切险" ZJID="100" Unit="总额" Quantity="1" Rate="500" Total="500" Remark="" Sequence="4" IsPriceCeiling="False"/>
- <BQItem BQItemID="221" Code="101-1-2" Name="按合同条款规定,提供第三者责任险" ZJID="100" Unit="总额" Quantity="1" Rate="600" Total="600" Remark="" Sequence="5" IsPriceCeiling="False"/>
- </BQTitle> }
- // ABQTitle、ABillItem 对应于同级
- procedure LoadBQItems(ABQTitle: TXmlNode; ABillItem: TScBillsItem);
- var j: Integer;
- vBQItem, vPBQItem: TXmlNode;
- sCode: string;
- vCurItem, vCurItemParent: TScBillsItem;
- iPreSptr, iCurSptr, iParentID, iPSptr: Integer;
- begin
- iPreSptr := -1;
- for j := 0 to ABQTitle.ElementCount - 1 do
- begin
- vBQItem := ABQTitle.Elements[j];
- sCode := vBQItem.AttributeValueByNameUTF8['Code'];
- iCurSptr := GetSeparatorCount(sCode);
- if iPreSptr = -1 then // 第一个结点
- iParentID := ABillItem.ID
- else
- begin
- if iCurSptr = iPreSptr then // 当前清单的分隔符等于上一条,则是后兄弟
- iParentID := vCurItem.ParentID
- else if iCurSptr > iPreSptr then // 多于则是孩子
- iParentID := vCurItem.ID
- else // 小于则表示比上一条级别高,高多少级未知
- begin
- vCurItemParent := TScBillsItem(vCurItem.Parent);
- while Assigned(vCurItemParent) do // 找同级别的结点
- begin
- iPSptr := GetSeparatorCount(vCurItemParent.Code);
- if iPSptr = iCurSptr then
- begin
- iParentID := vCurItemParent.ParentID;
- Break;
- end;
- if iPSptr = 0 then Break; // 截止到编号如"101",则不再往上找。
- vCurItemParent := TScBillsItem(vCurItemParent.Parent);
- end;
- end;
- end;
- ABillItem.LocateInControl;
- vCurItem := TScProject(FProject).Bills.BillsTree.AddBillsItem(iParentID, -1);
- with vCurItem.Rec do
- begin
- BeginUpdate;
- Code.AsString := sCode;
- Name.AsString := vBQItem.AttributeValueByNameUTF8['Name'];
- MemoStr.AsString := vBQItem.AttributeValueByNameUTF8['Remark'];
- Units.AsString := vBQItem.AttributeValueByNameUTF8['Unit'];
- Quantity.AsString := vBQItem.AttributeValueByNameUTF8['Quantity'];
- UnitPrice.AsString := vBQItem.AttributeValueByNameUTF8['Rate'];
- if StrToIntDef(vBQItem.AttributeValueByNameUTF8['Rate'], 0) <> 0 then
- begin
- TotalPrice.AsString := vBQItem.AttributeValueByNameUTF8['Total'];
- // lsIsLeaf.AsBoolean := True; 新版lsIsLeaf读的是HasChildren方法,不是lsIsLeaf字段。不能识别,暂时注释,用到时再处理
- end;
- CalcFlag.AsInteger := Flag_CustomTotalPrice;
- EndUpdate;
- end;
- iPreSptr := iCurSptr;
- end;
- end;
- // 筑龙这里的结构是拼凑的,用不了递归。很山寨,只好跟着它拼,鄙视筑龙的技术!
- procedure LoadDayWork(ANode: TXmlNode);
- var i, j: Integer;
- vNode1, vNode2: TXmlNode;
- vItem1, vParentItem: TScBillsItem;
- function AddItem(AParentItem: TScBillsItem; ANode: TXmlNode): TScBillsItem;
- var vtem: TScBillsItem;
- begin
- vtem := TScProject(FProject).Bills.BillsTree.AddBillsItem(AParentItem.ID, -1);
- with vtem.Rec do
- begin
- BeginUpdate;
- Code.AsString := ANode.AttributeValueByNameUTF8['Code'];
- Name.AsString := ANode.AttributeValueByNameUTF8['Name'];
- MemoStr.AsString := ANode.AttributeValueByNameUTF8['Remark'];
- Units.AsString := ANode.AttributeValueByNameUTF8['Unit'];
- Quantity.AsString := ANode.AttributeValueByNameUTF8['Quantity'];
- UnitPrice.AsString := ANode.AttributeValueByNameUTF8['Rate'];
- if StrToIntDef(ANode.AttributeValueByNameUTF8['Rate'], 0) <> 0 then
- begin
- TotalPrice.AsString := ANode.AttributeValueByNameUTF8['Total'];
- IsLeaf.AsBoolean := True;
- end;
- CalcFlag.AsInteger := Flag_CustomTotalPrice;
- EndUpdate;
- end;
- Result := vtem;
- end;
- begin
- with TScProject(FProject).Bills do
- begin
- for i := 0 to ANode.ElementCount - 1 do
- begin
- vNode1 := ANode.Elements[i];
- if vNode1.AttributeValueByNameUTF8['CostKind'] = '1' then
- vParentItem := BillsTree[idDayWorkLabour]
- else if vNode1.AttributeValueByNameUTF8['CostKind'] = '2' then
- vParentItem := BillsTree[idDayWorkMaterial]
- else if vNode1.AttributeValueByNameUTF8['CostKind'] = '3' then
- vParentItem := BillsTree[idDayWorkMachine];
- vItem1 := AddItem(vParentItem, vNode1);
- for j := 0 to vNode1.ElementCount - 1 do
- begin
- vNode2 := vNode1.Elements[j];
- AddItem(vItem1, vNode2);
- end;
- end;
- end;
- end;
- function FindItemByName(AName: string): TScBillsItem;
- var i: Integer;
- begin
- Result := nil;
- with TScProject(FProject).Bills do
- begin
- for i := 0 to BillsTree.Count - 1 do
- begin
- if BillsTree.Items[i].Name = AName then
- begin
- Result := BillsTree.Items[i];
- Break;
- end;
- end;
- end;
- end;
- procedure LoadZGJ(ANode: TXmlNode; AInterim: Integer);
- var vNdoe: TXmlNode;
- vItem: TScBillsItem;
- i: Integer;
- begin
- for i := 0 to ANode.ElementCount - 1 do
- begin
- vNdoe := ANode.Elements[i];
- vItem := FindItemByName(vNdoe.AttributeValueByNameUTF8['Name']);
- if Assigned(vItem) then
- begin
- vItem.Rec.BeginUpdate;
- vItem.Rec.IsSpecialInterim.AsBoolean := True;
- vItem.Rec.InterimType.AsInteger := AInterim;
- vItem.Rec.EndUpdate;
- end;
- end;
- end;
- procedure LoadPropertities(ANode: TXmlNode);
- var i: Integer;
- vNode1: TXmlNode;
- strName, sValue, sBildUnit, sBidder, sAuthor: string;
- begin
- for i := 0 to ANode.ElementCount - 1 do
- begin
- vNode1 := ANode.Elements[i];
- strName := vNode1.AttributeValueByNameUTF8['Name'];
- sValue := vNode1.AttributeValueByNameUTF8['Value'];
- if strName = '招标人(建设单位)' then
- sBildUnit := sValue
- else if strName = '编制单位' then
- sBidder := sValue
- else if strName = '编制单位法定代表人' then
- sAuthor := sValue;
- end;
- TScProjBaseData(TScProject(FProject).ProjData).LoadValuesByXML(sBildUnit, sBidder, sAuthor);
- end;
- var
- OldRealTimeCalc: Boolean;
- begin
- inherited;
- OldRealTimeCalc := TScProject(FProject).RealTimeCalc;
- try
- TScProject(FProject).RealTimeCalc := False;
- with TScProject(FProject).Bills do
- begin
- vSingleProject := FRoot.FindNode('SingleProject');
- vUnitProject := vSingleProject.FindNode('UnitProject');
- vBQTable := vUnitProject.FindNode('BQTable');
- // 删除第一部分的子结点
- BillsTree.DeleteChildren(BillsTree[idNormalBillsRoot]);
-
- for i := 0 to vBQTable.ElementCount - 1 do // 章节结点
- begin
- vBQTitle := vBQTable.Elements[i];
- vItem := BillsTree.AddBillsItem(idNormalBillsRoot, -1);
- with vItem.Rec do
- begin
- BeginUpdate;
- Name.AsString := vBQTitle.AttributeValueByNameUTF8['Name'];
- MemoStr.AsString := vBQTitle.AttributeValueByNameUTF8['Remark'];
- EndUpdate;
- end;
- LoadBQItems(vBQTitle, vItem);
- end;
- // 导入计日工
- vNode := vUnitProject.FindNode('DayWorkTable');
- // vItem := BillsTree[idDayWork];
- // LoadDayWorkItems(vNode.Elements[0],vItem); // 后参数比前参数高一级
- if Assigned(vNode) then
- LoadDayWork(vNode);
- // 暂估价
- vNode := vUnitProject.FindNode('MaterialProvisionalPriceTable');
- if Assigned(vNode) then
- LoadZGJ(vNode, 1);
- vNode := vUnitProject.FindNode('ProjEquipmentPriceTable');
- if Assigned(vNode) then
- LoadZGJ(vNode, 2);
- vNode := vUnitProject.FindNode('ProjProvisionalPriceTable');
- if Assigned(vNode) then
- LoadZGJ(vNode, 3);
- // 标段属性
- vNode := FRoot.FindNode('ProjectAddInfo');
- if Assigned(vNode) then
- LoadPropertities(vNode);
- TScProject(FProject).Bills.CalculateAll;
- // 最后存储
- TScProjBaseData(TScProject(FProject).ProjData).Save;
- end;
- finally
- TScProject(FProject).RealTimeCalc := OldRealTimeCalc;
- end;
- end;
- procedure TkmXMLPort.AddRoot;
- begin
- FRoot.Name := 'ConstructProject';
- FRoot.AttributeAddUTF8('Code', '0');
- FRoot.AttributeAddUTF8('Name', PD.BuildProjectName);
- FRoot.AttributeAddUTF8('Tenderee', '');
- FRoot.AttributeAddUTF8('TendereeProxy', '');
- FRoot.AttributeAddUTF8('Standard', '昆明市工程造价数据交换标准');
- FRoot.AttributeAddUTF8('StandardVer', '1.0');
- FRoot.AttributeAddUTF8('FileType', IntToStr(Ord(FFileType)));
- FRoot.AttributeAddUTF8('InterfaceCode', '');
- end;
- { TzhXMLPort }
- procedure TzhXMLPort.AddRoot;
- begin
- inherited;
- FRoot.Name := '文件信息';
- // 日期和时间是客户机的,因而意义不大,无需精确。本时间仅作为文件收集时间的一个参考,入库用服务器的时间
- FRoot.AttributeAddUTF8('日期', FormatDateTime('yyyy-mm-dd', Date));
- FRoot.AttributeAddUTF8('建设项目', PD.BuildProjectName);
- FRoot.AttributeAddUTF8('标段', PD.Alias);
- FRoot.AttributeAddUTF8('地区', TScProject(FProject).FeeRate.cdsFeeParams2.Lookup('ID', 1, 'Caption'));
- if TScProject(FProject).IsQuanGuo then
- FRoot.AttributeAddUTF8('区域版本', '全国')
- else
- FRoot.AttributeAddUTF8('区域版本', '广东');
- if TScProject(FProject).IsBills then
- FRoot.AttributeAddUTF8('分段类型', '招投标')
- else if TScProject(FProject).IsBudget then
- FRoot.AttributeAddUTF8('分段类型', '估概预')
- else if TScProject(FProject).IsGD3J then
- FRoot.AttributeAddUTF8('分段类型', '三级清单');
- end;
- { TgljXMLPort }
- procedure TgljXMLPort.AddRoot;
- begin
- inherited;
- FRoot.AttributeAddUTF8('数据分类', 'GLJPrice');
- end;
- procedure TgljXMLPort.AddDetail;
- procedure AddProjectGLJ;
- var vPNode, vNode: TXmlNode;
- begin
- vPNode := FRoot.NodeNewUTF8('项目工料机');
- FQuery1.Close;
- FQuery1.SQL.Text :=
- 'Select Code, Name, Specs, Unit, Type, BudgetPrice from ProjectGLJ where (New = False) and ((type = 3) or (type = 4)) and (BudgetPrice > 0) order by Code';
- FQuery1.Open;
- FQuery1.First;
- while not FQuery1.Eof do
- begin
- vNode := vPNode.NodeNewUTF8('ProjectGLJ');
- vNode.AttributeAddUTF8('Code', FQuery1.FieldByName('Code').AsString);
- vNode.AttributeAddUTF8('Name', FQuery1.FieldByName('Name').AsString);
- vNode.AttributeAddUTF8('Spec', FQuery1.FieldByName('Specs').AsString);
- vNode.AttributeAddUTF8('Unit', ChangeUnit_m3(FQuery1.FieldByName('Unit').AsString));
- vNode.AttributeAddUTF8('Type', FQuery1.FieldByName('Type').AsString);
- vNode.AttributeAddUTF8('Price', Format('%.2f', [FQuery1.FieldByName('BudgetPrice').AsFloat]));
- vNode.AttributeAddUTF8('Lib', '1'); // 部颁工料机
- FQuery1.Next;
- end;
- FQuery1.Close;
- end;
- procedure AddUserGLJ;
- var vUNode, vNode: TXmlNode;
- aqUserGLJ: TADOQuery;
- begin
- vUNode := FRoot.NodeNewUTF8('用户工料机');
- aqUserGLJ := TADOQuery.Create(nil);
- try
- aqUserGLJ.Connection := UserGLJLib.acGLJLib;
- aqUserGLJ.Close;
- aqUserGLJ.SQL.Text :=
- 'Select Code, Name, Specs, Unit, Type, BasePrice from GLJList where ((type = 3) or (type = 4)) and (BasePrice > 0) order by Code';
- aqUserGLJ.Open;
- aqUserGLJ.First;
- while not aqUserGLJ.Eof do
- begin
- vNode := vUNode.NodeNewUTF8('UserGLJ');
- vNode.AttributeAddUTF8('Code', aqUserGLJ.FieldByName('Code').AsString);
- vNode.AttributeAddUTF8('Name', aqUserGLJ.FieldByName('Name').AsString);
- vNode.AttributeAddUTF8('Spec', aqUserGLJ.FieldByName('Specs').AsString);
- vNode.AttributeAddUTF8('Unit', ChangeUnit_m3(aqUserGLJ.FieldByName('Unit').AsString));
- vNode.AttributeAddUTF8('Type', aqUserGLJ.FieldByName('Type').AsString);
- vNode.AttributeAddUTF8('Price', Format('%.2f', [aqUserGLJ.FieldByName('BasePrice').AsFloat]));
- vNode.AttributeAddUTF8('Lib', '2'); // 自定义工料机
- aqUserGLJ.Next;
- end;
- aqUserGLJ.Close;
- finally
- aqUserGLJ.Free;
- end;
- end;
- begin
- inherited;
- // 简化逻辑,不再区分,统一由项目属性值控制。一天同时打印多个项目导致全局数据
- // 重复上传的机率很小吧?即使有,也无所谓,这点数据对于硬件来说实属小菜。
- AddProjectGLJ;
- AddUserGLJ;
- end;
- { TbpXMLPort }
- procedure TbpXMLPort.AddRoot;
- begin
- inherited;
- FRoot.AttributeAddUTF8('数据分类', 'BillPrice');
- end;
- procedure TbpXMLPort.AddDetail;
- var iBID: Integer;
- procedure AddItems;
- var vPNode, vNode: TXmlNode;
- sCodeField: string;
- begin
- vPNode := FRoot.NodeNewUTF8('叶子清单');
- if TScProject(FProject).IsQuanGuo then // 全国Code显示的是短编号如“1”“-a”等
- sCodeField := 'Fullcode'
- else
- sCodeField := 'Code';
- FQuery1.Close;
- FQuery1.SQL.Text := Format('Select Distinct %0:s, B_Code, Name, Units, IIF(UnitPrice is null, 0, UnitPrice) as UnitPrice, IIF(DesignPrice is null, 0, DesignPrice) as DesignPrice ' +
- 'from Bills where (IsLeaf = True) and ((UnitPrice<> 0) or (DesignPrice<> 0)) and ' +
- '((%0:s <> '''') or (B_Code <> '''')) order by %0:s, B_Code', [sCodeField]);
- FQuery1.Open;
- FQuery1.First;
- while not FQuery1.Eof do
- begin
- vNode := vPNode.NodeNewUTF8('BillItem');
- vNode.AttributeAddUTF8('Code', FQuery1.FieldByName(sCodeField).AsString);
- vNode.AttributeAddUTF8('B_Code', FQuery1.FieldByName('B_Code').AsString);
- vNode.AttributeAddUTF8('Name', FQuery1.FieldByName('Name').AsString);
- vNode.AttributeAddUTF8('Units', ChangeUnit_m3(FQuery1.FieldByName('Units').AsString));
- vNode.AttributeAddUTF8('UnitPrice', FQuery1.FieldByName('UnitPrice').AsString);
- vNode.AttributeAddUTF8('DesignPrice', FQuery1.FieldByName('DesignPrice').AsString);
- FQuery1.Next;
- end;
- FQuery1.Close;
- end;
- begin
- inherited;
- AddItems;
- end;
- //*****************************************芜湖接口*************************************************************************
- { TwhXMLPort }
- procedure TwhXMLPort.AddRoot;
- begin
- inherited;
- FRoot.Name := 'JingJiBiao';
- FRoot.AttributeAddUTF8('Xmbh', IntToStr(PD.BuildProjectID));
- FRoot.AttributeAddUTF8('Xmmc', PD.BuildProjectName);
- FRoot.AttributeAddUTF8('Bzlx', '清单');
- FRoot.AttributeAddUTF8('Jjyj', '【18清单】2018部颁清单计价依据'); // 【18清单】2018部颁清单计价依据
- FRoot.AttributeAddUTF8('Xmqzzh', PV('StartCode'));
- FRoot.AttributeAddUTF8('Jsdw', PD.BuildUnit);
- case FFileType of
- xftZB: FRoot.AttributeAddUTF8('Czzt', '招标');
- xftTB: FRoot.AttributeAddUTF8('Czzt', '投标');
- xftKZJ: FRoot.AttributeAddUTF8('Czzt', '招标控制');
- end;
- FRoot.AttributeAddUTF8('Jsfs', '1');
- FRoot.AttributeAddUTF8('Version', '1.0');
- end;
- procedure TwhXMLPort.AddDetail;
- procedure AddHeadXx;
- var vNode: TXmlNode;
- sKey: string;
- begin
- case FFileType of
- xftZB: sKey := 'ZhaoBiaoXx';
- xftTB: sKey := 'TouBiaoXx';
- xftKZJ: sKey := 'ZhaoBiaoKzXx';
- end;
- vNode := FRoot.NodeNewUTF8(sKey);
- case FFileType of
- xftZB, xftKZJ:
- begin
- vNode.AttributeAddUTF8('Zbr', '招标人');
- vNode.AttributeAddUTF8('Zxr', '咨询人');
- vNode.AttributeAddUTF8('ZbrDb', '招标人代表');
- vNode.AttributeAddUTF8('ZxrDb', '咨询人代表');
- vNode.AttributeAddUTF8('Bzr', PD.Author);
- vNode.AttributeAddUTF8('Fhr', PD.Auditor);
- vNode.AttributeAddUTF8('BzTime', Copy(DateToStr(PD.EditDate), 1, 10));
- vNode.AttributeAddUTF8('FhTime', Copy(DateToStr(PD.EditDate), 1, 10));
- if FFileType = xftKZJ then
- begin
- vNode.AttributeAddUTF8('Zbkzj', '');
- end;
- end;
- xftTB: // <TouBiaoXx Zbr="招标人" Tbr="投标人" TbrDb="" Bzr="" BzTime="2019-06-06" Tbzj="639621.47" />
- begin
- vNode.AttributeAddUTF8('Zbr', '招标人');
- vNode.AttributeAddUTF8('Tbr', '投标人');
- vNode.AttributeAddUTF8('TbrDb', '投标人代表');
- vNode.AttributeAddUTF8('Bzr', PD.Author);
- vNode.AttributeAddUTF8('BzTime', Copy(DateToStr(PD.EditDate), 1, 10));
- vNode.AttributeAddUTF8('Tbzj', GetProjectTotalPrice);
- end;
- end;
- end;
- procedure AddJjFlb;
- var sSQL: string;
- begin
- sSQL :=
- 'Select Name as , Code, Unit, Quantity, ' +
- 'UnitDirectFee as Rate, BuildingFee as Total, ' +
- 'SerialNo as Sequence ' +
- 'from Fees';
- AddTabToXML(FQuery1, sSQL, FJjFlbNode, '', 'JjFlbMx');
- end;
- procedure AddJjFlx;
- var sSQL: string;
- begin
- sSQL :=
- 'Select SerialNo as Bm, Name as Mc, Caption as ShuZhi ' +
- 'from FeeParams Order by SerialNo';
- AddTabToXML(FQuery2, sSQL, FJjFlxNode, '', 'JjFlxMx');
- end;
- procedure AddQfxx;
- begin
- FQfxxNode := FDwgcxxNode.NodeNewUTF8('Qfxx');
- FJjFlbNode := FQfxxNode.NodeNewUTF8('JjFlb');
- FJjFlxNode := FQfxxNode.NodeNewUTF8('JjFlx');
- // AddJjFlb;
- AddJjFlx;
- end;
- function Rec(ANode: TScBillsItem; AName: string): string;
- begin
- Result := ANode.Rec.ValueByName(AName).AsString;
- end;
- procedure ReadTreeNodes(ANode: TScBillsItem; AXMLParent: TXmlNode);
- var vXMLNode, vRationNode, vRationMxNode, vGLJNode, vGLJMxNode: TXmlNode;
- begin
- if ANode <> nil then
- begin
- if ANode.Parent = nil then
- begin
- Inc(FBlackFontBillsNo);
- vXMLNode := AXMLParent.NodeNewUTF8('QdBt');
- vXMLNode.AttributeAddUTF8('Xh', IntToStr(FBlackFontBillsNo));
- vXMLNode.AttributeAddUTF8('Bm', ANode.Code);
- vXMLNode.AttributeAddUTF8('Name', ANode.Name);
- vXMLNode.AttributeAddUTF8('Je', Rec(ANode, 'TotalPrice'));
- vXMLNode.AttributeAddUTF8('Code', '');
- vXMLNode.AttributeAddUTF8('Jsgs', '');
- vXMLNode.AttributeAddUTF8('Lb', IntToStr(FBlackFontBillsNo));
- vXMLNode.AttributeAddUTF8('Bz', Rec(ANode, 'MemoStr'));
- if FBlackFontBillsNo = 4 then // 计日工合计
- begin
- FJrgNode := vXMLNode.NodeNewUTF8('Jrg');
- vXMLNode := FJrgNode;
- end;
- end
- else
- begin
- if AXMLParent = FJrgNode then
- begin
- vXMLNode := AXMLParent.NodeNewUTF8('JrgBt');
- vXMLNode.AttributeAddUTF8('Name', ANode.Name);
- vXMLNode.AttributeAddUTF8('Je', Rec(ANode, 'TotalPrice'));
- if Pos('劳务', ANode.Name) > 0 then
- vXMLNode.AttributeAddUTF8('Lb', '1')
- else if Pos('材料', ANode.Name) > 0 then
- vXMLNode.AttributeAddUTF8('Lb', '2')
- else if Pos('机械', ANode.Name) > 0 then
- vXMLNode.AttributeAddUTF8('Lb', '3');
- vXMLNode.AttributeAddUTF8('Bz', Rec(ANode, 'MemoStr'));
- end
- else
- begin
- vXMLNode := AXMLParent.NodeNewUTF8('QdMx');
- vXMLNode.AttributeAddUTF8('Xh', Rec(ANode, 'SerialNo'));
- vXMLNode.AttributeAddUTF8('Qdbm', ANode.Code);
- vXMLNode.AttributeAddUTF8('Name', ANode.Name);
- vXMLNode.AttributeAddUTF8('Xmtz', '');
- vXMLNode.AttributeAddUTF8('Dw', Rec(ANode, 'Units'));
- vXMLNode.AttributeAddUTF8('Sl', Rec(ANode, 'Quantity'));
- vXMLNode.AttributeAddUTF8('Sl2', '0');//Rec(ANode, 'Quantity2');
- vXMLNode.AttributeAddUTF8('Rgf', '0');
- vXMLNode.AttributeAddUTF8('Clf', '0');
- vXMLNode.AttributeAddUTF8('Jxf', '0');
- vXMLNode.AttributeAddUTF8('Sbf', '0');
- vXMLNode.AttributeAddUTF8('Csf', '0');
- vXMLNode.AttributeAddUTF8('Glf', '0');
- vXMLNode.AttributeAddUTF8('Gf', '0');
- vXMLNode.AttributeAddUTF8('Lr', '0');
- vXMLNode.AttributeAddUTF8('Sj', '0');
- if FFileType in [xftTB, xftKZJ] then
- begin
- vXMLNode.AttributeAddUTF8('Zhdj', Rec(ANode, 'UnitPrice'));
- vXMLNode.AttributeAddUTF8('Zhhj', Rec(ANode, 'TotalPrice'));
- end
- else
- begin
- vXMLNode.AttributeAddUTF8('Zhdj', '0');
- vXMLNode.AttributeAddUTF8('Zhhj', '0');
- end;
- vXMLNode.AttributeAddUTF8('Zgj', '0');
- vXMLNode.AttributeAddUTF8('Iszg', 'false');
- vXMLNode.AttributeAddUTF8('Djfx', 'true');
- vXMLNode.AttributeAddUTF8('Jsgs', '');
- vXMLNode.AttributeAddUTF8('Bl', '');
- vXMLNode.AttributeAddUTF8('Bz', Rec(ANode, 'MemoStr'));
- if FFileType = xftTB then
- begin
- if ANode.IsLeaf then
- begin
- FQuery2.Close;
- FQuery2.SQL.Clear;
- FQuery2.SQL.Add(Format('SELECT * FROM RationCalcList WHERE BillsItemID = %d', [ANode.ID]));
- FQuery2.Open;
- if FQuery2.RecordCount > 0 then
- begin
- vRationNode := vXMLNode.NodeNewUTF8('Qdxdezj');
- FQuery2.First;
- while not FQuery2.Eof do
- begin
- vRationMxNode := vRationNode.NodeNewUTF8('QdxdezjMx');
- vRationMxNode.AttributeAddUTF8('Debm', FQuery2.FieldByName('Code').asString);
- vRationMxNode.AttributeAddUTF8('Mc', FQuery2.FieldByName('Name').asString);
- vRationMxNode.AttributeAddUTF8('Dw', FQuery2.FieldByName('Unit').asString);
- vRationMxNode.AttributeAddUTF8('Sl', FQuery2.FieldByName('Quantity').asString);
- vRationMxNode.AttributeAddUTF8('Dj', FQuery2.FieldByName('UnitPrice').asString);
- vRationMxNode.AttributeAddUTF8('Hj', FQuery2.FieldByName('BuildingFee').asString);
- vRationMxNode.AttributeAddUTF8('Rgf', FQuery2.FieldByName('LabourFee').asString);
- vRationMxNode.AttributeAddUTF8('Clf', FQuery2.FieldByName('MaterialFee').asString);
- vRationMxNode.AttributeAddUTF8('Jxf', FQuery2.FieldByName('MachineFee').asString);
- vRationMxNode.AttributeAddUTF8('Sbf', '0');
- vRationMxNode.AttributeAddUTF8('Csf', FQuery2.FieldByName('OtherDirectFee').asString);
- vRationMxNode.AttributeAddUTF8('Glf', FQuery2.FieldByName('ManageFee').asString);
- vRationMxNode.AttributeAddUTF8('Gf', FQuery2.FieldByName('LocaleFee').asString);
- vRationMxNode.AttributeAddUTF8('Lr', FQuery2.FieldByName('Profit').asString);
- vRationMxNode.AttributeAddUTF8('Sj', FQuery2.FieldByName('Tax').asString);
- case FQuery2.FieldByName('Type').AsInteger of
- 0: vRationMxNode.AttributeAddUTF8('Delb', '1');
- 1:
- begin
- if FQuery2.FieldByName('IsMECalc').AsBoolean then
- vRationMxNode.AttributeAddUTF8('Delb', '5') // 设备
- else
- begin
- case FQuery2.FieldByName('CountPriceType').AsInteger of
- 1: vRationMxNode.AttributeAddUTF8('Delb', '2'); // 数量单价人工
- 2: vRationMxNode.AttributeAddUTF8('Delb', '3'); // 数量单价材料
- 3: vRationMxNode.AttributeAddUTF8('Delb', '4'); // 数量单价机械
- end;
- end;
- end;
- end;
- vRationMxNode.AttributeAddUTF8('Iszd', 'false');
- FQuery3.Close;
- FQuery3.SQL.Clear;
- FQuery3.SQL.Add(Format('SELECT * FROM GLJList WHERE RationID = %d', [FQuery2.FieldByName('ID').AsInteger]));
- FQuery3.Open;
- if FQuery3.RecordCount > 0 then
- begin
- vGLJNode := vRationMxNode.NodeNewUTF8('Qdxdercjhl');
- FQuery3.First;
- while not FQuery3.Eof do
- begin
- vGLJMxNode := vGLJNode.NodeNewUTF8('QdxdercjhlMx');
- vGLJMxNode.AttributeAddUTF8('RcjId', FQuery3.FieldByName('GLJID').asString);
- vGLJMxNode.AttributeAddUTF8('Sl', FQuery3.FieldByName('Quantity').asString);
- FQuery3.Next;
- end;
- end;
- FQuery3.Close;
- FQuery2.Next;
- end;
- vXMLNode.NodeNewUTF8('Qdxrcjhl');
- end;
- FQuery2.Close;
- end;
- end;
- end;
- end;
- // 第3层计日工不导出:导出要换内容,太复杂且毫无意义。
- if (ANode.Parent <> nil) and (TScBillsItem(ANode.Parent).Name = '计日工合计') then
- begin
- end
- else
- ReadTreeNodes(TScBillsItem(ANode.FirstChild), vXMLNode);
- ReadTreeNodes(TScBillsItem(ANode.NextSibling), AXMLParent);
- end;
- end;
- procedure AddQdXm;
- var vTree: TScBillsTree;
- begin
- FQdXmNode := FDwgcxxNode.NodeNewUTF8('QdXm');
- vTree := TScProject(FProject).Bills.BillsTree;
- FBlackFontBillsNo := 0;
- ReadTreeNodes(vTree.Items[0], FQdXmNode);
- end;
- procedure AddZgCl;
- var vNode: TXmlNode;
- begin
- FZgClNode := FDwgcxxNode.NodeNewUTF8('ZgCl');
- end;
- procedure AddJpCl;
- var vNode: TXmlNode;
- begin
- FJpClNode := FDwgcxxNode.NodeNewUTF8('JpCl');
- end;
- procedure AddRcjhz;
- var vNode: TXmlNode;
- sSQL: string;
- begin
- FRcjhzNode := FDwgcxxNode.NodeNewUTF8('Rcjhz');
- // sSQL :=
- // 'Select ID as RcjId, Code as RcjBm, Name, Specs as Ggxh, Unit as Dw, ' +
- // 'BudgetPrice as Dj, Amount as Sl, BudgetPrice*Amount as Hj, '''' as Cd, '''' as Gycs, Type as Rcjlb, ''false'' as Jgbz,' +
- // 'Main as Zyclbz, ''false'' as Zgjbz, ''false'' as Zcbz ' +
- // 'from ProjectGLJ';
- sSQL :=
- 'Select ID as RcjId, Code as RcjBm, Name, Specs as Ggxh, Unit as Dw, ' +
- 'BudgetPrice as Dj, Amount as Sl, BudgetPrice*Amount as Hj, '''' as Cd, '''' as Gycs, IIF(Type=2 or Type=4,2,IIF(Type=6 or Type=8,3,Type)) as Rcjlb, ''false'' as Jgbz,' +
- 'Main as Zyclbz, ''false'' as Zgjbz, ''false'' as Zcbz ' +
- 'from ProjectGLJ ' +
- 'where Type <> 9';
- AddTabToXML(FQuery1, sSQL, FRcjhzNode, '', 'RcjhzMx');
- end;
- procedure AddDwgcxx;
- var vNode: TXmlNode;
- begin
- vNode := FDxgcxxNode.NodeNewUTF8('Dwgcxx');
- vNode.AttributeAddUTF8('Dwgcbh', '珠海纵横创新软件有限公司');
- vNode.AttributeAddUTF8('Dwgcmc', PD.BuildProjectName);
- FDwgcxxNode := vNode;
- AddProgressForm(10, '正在导出取费信息...');
- AddQfxx;
- AddProgressForm(10, '正在导出清单项目...');
- AddQdXm;
- AddProgressForm(10, '正在导出暂估材料表...');
- AddZgCl;
- AddProgressForm(10, '正在导出甲评材料表...');
- AddJpCl;
- AddProgressForm(10, '正在导出人材机汇总...');
- if FFileType in [xftTB, xftKZJ] then
- begin
- AddRcjhz;
- end;
- end;
- procedure AddDxgcxx;
- var vNode: TXmlNode;
- begin
- vNode := FRoot.NodeNewUTF8('Dxgcxx');
- vNode.AttributeAddUTF8('Dxgcbh', '珠海纵横创新软件有限公司');
- vNode.AttributeAddUTF8('Dxgcmc', PD.BuildProjectName);
- FDxgcxxNode := vNode;
- AddDwgcxx;
- end;
- procedure AddJyxx;
- var vNode: TXmlNode;
- begin
- AddProgressForm(10, '正在生成校验信息...');
- vNode := FRoot.NodeNewUTF8('Jyxx');
- vNode.AttributeAddUTF8('SoftName', Application.Title);
- vNode.AttributeAddUTF8('SoftNum', 'SamrtCost10.1');
- vNode.AttributeAddUTF8('MacAdress', Get_MAC_Address);
- vNode.AttributeAddUTF8('DogNum', 'SCDOG001002');
- vNode.AttributeAddUTF8('ComputerName', Get_Computer_Name);
- vNode.AttributeAddUTF8('HDDSerial', Get_HDD_SN);
- vNode.AttributeAddUTF8('CPUSerial', Get_CPU_SN);
- end;
- begin
- inherited;
- AddHeadXx;
- AddDxgcxx;
- AddJyxx;
- end;
- { TtzslXMLPort }
- function TtzslXMLPort.CheckXMLFile: Boolean;
- var
- sType: string;
- iProjType: Integer;
- begin
- Result := True;
- FInfo := FRoot.FindNode('Info');
- if FInfo <> nil then
- sType := VarToStr(FInfo.AttributeValueByNameUTF8['DataType'])
- else
- sType := '';
- if (FInfo = nil) or (sType = '') then
- begin
- MessageHint(0, '文件错误,请使用从算量软件导出的XML文件!');
- Result := False;
- Exit;
- end;
- // 2023/11/13 zhangyin 开始支持平级清单
- (*if FFirstBill.ElementCount = 0 then
- begin
- MessageHint(0, '不支持导入平级的清单结构,请使用有树结构层次的清单!');
- Result := False;
- Exit;
- end; *)
- iProjType := Ord(TScProject(FProject).ProjType);
- Result := (SameText(sType, 'Fx') and (iProjType in [5])) or // 三级清单
- (SameText(sType, 'Gcl') and (iProjType in [0])) or // 清单
- (SameText(sType, 'Xmj') and (iProjType in [1,2,3,4,6,7,8,9])); // 项目节
- FIsBills := SameText(sType, 'Gcl');
- if not Result then
- begin
- MessageHint(0, '操作失败,XML文件与当前项目的项目类型不匹配!');
- Exit;
- end;
-
- FBillList := FRoot.FindNode('BillList');
- FFirstBill := FBillList.Elements[0];
- // 清单只有一个父项
- if not FIsBills then
- begin
- if FBillList.ElementCount > 1 then
- FSecondBill := FBillList.Elements[1];
- if FBillList.ElementCount > 2 then
- FThirdBill := FBillList.Elements[2];
- if FBillList.ElementCount > 3 then
- FFourthBill := FBillList.Elements[3];
- end;
- end;
- procedure TtzslXMLPort.AnalyzeXMLNodesIntoList(ASelectItem: TScBillsItem);
- var vFile: TextFile;
- isTest: Boolean;
- procedure AddNodesToList(ANode: TXmlNode);
- var P: PXMLNode;
- begin
- if ANode = nil then Exit;
- if (ANode.Name <> 'Bills') then Exit;
- // if (not ANode.HasChildNodes) or
- // (ANode.HasChildNodes and (ANode.Elements[0];.Name <> 'Bills')) then
- begin
- New(P);
- P^.Data := ANode;
- P^.FullCode := GetCompareFullCode(ANode);
- FXMLNodesList.Add(P);
- if isTest then
- Writeln(vFile, Format('%s %s %s %s', [P^.FullCode, ANode.AttributeValueByNameUTF8['Name'],
- ANode.AttributeValueByNameUTF8['Code'], ANode.AttributeValueByNameUTF8[FB_CodeFieldName]]));
- end;
- if Assigned(ANode.Elements[0]) then
- AddNodesToList(ANode.Elements[0]);
- // 当前Node有后兄弟, 且当前Node不是“第二部分 ...”才进入后兄弟。即:从"第三部分..." 开始不进入线性对比列表(它这里断了,它的后兄弟跟着全部都断了)。
- if Assigned(ANode.NextSibling(ANode)) and (Pos('第二部分', ANode.AttributeValueByNameUTF8['Name']) = 0) then
- AddNodesToList(ANode.NextSibling(ANode));
- end;
- // function GetSyncNode(AItem: TScBillsItem; ANode: IXMLNode; var ARstNode: IXMLNode): IXMLNode;
- // begin
- // if ANode = nil then Exit;
- // if (ANode.Name <> 'Bills') then Exit;
- //
- // if (ANode.AttributeAdd('Code'] = AItem.Code) and
- // (ANode.AttributeAdd('b_Code'] = AItem.B_Code) and
- // (ANode.AttributeAdd('Name'] = AItem.Name) and
- // SameText(GetFullCode(ANode), AItem.FullCode) then
- // begin
- // ARstNode := ANode;
- // Exit;
- // end;
- //
- // if ARstNode = nil then
- // begin
- // if Assigned(ANode.NextSibling) then
- // GetSyncNode(AItem, ANode.NextSibling, ARstNode);
- //
- // if Assigned(ANode.Elements[0]) then
- // GetSyncNode(AItem, ANode.Elements[0], ARstNode);
- // end;
- // end;
- var vFromNode: TXmlNode;
- begin
- isTest := True;
- DisposeXMLNodesList;
- // if ASelectItem.ID = 1 then
- // vFromNode := FFirstBill.Elements[0]
- // else
- // GetSyncNode(ASelectItem, FFirstBill.Elements[0], vFromNode);
- // vFromNode := FFirstBill.Elements[0];
- vFromNode := FFirstBill;
- if isTest then AssignFile(vFile, ExtractFilePath(Application.ExeName) + 'UserData\OrgXML.test');
- try
- if isTest then ReWrite(vFile);
- AddNodesToList(vFromNode);
- finally
- if isTest then CloseFile(vFile);
- end;
- end;
- procedure TtzslXMLPort.LoadFromXML;
- var
- OldRealTimeCalc: Boolean;
- vNode: TXmlNode;
- vItem, vItem2, vItem3, vItem4: TScBillsItem;
- begin
- inherited;
- if not CheckXMLFile then Exit;
- Screen.Cursor := crHourGlass;
- CreateProgressForm(100, '导入算量XML文件');
- OldRealTimeCalc := TScProject(FProject).RealTimeCalc;
- try
- TScProject(FProject).RealTimeCalc := False;
- FXMLNodeList := TList.Create;
- vItem := BillsTree[idNormalBillsRoot];
- // 删除第100章到700/900章清单/第一部分的子结点
- BillsTree.DeleteChildren(vItem);
- if not FIsBills then
- begin
- if Assigned(FSecondBill) then
- begin
- vItem2 := BillsTree[idSecondSection];
- // 删除第二部分的子结点
- BillsTree.DeleteChildren(vItem2);
- end;
- if Assigned(FThirdBill) then
- begin
- vItem3 := BillsTree[idThreeSection];
- // 删除第三部分的子结点
- BillsTree.DeleteChildren(vItem3);
- end;
- if Assigned(FFourthBill) then
- begin
- vItem4 := BillsTree[idFourthSection];
- // 删除第四部分的子结点
- BillsTree.DeleteChildren(vItem4);
- end;
- end;
- TScProject(FProject).Bills.CalculateAll; // 导入到有数据的项目时,因根结点有金额,不让导入,且内存崩溃
- BillsTree.SelectedIndex := -1; // 这句不加成不了树结构。
- // 清单为平面列表
- if FIsBills then
- begin
- AddProgressForm(10, '正在导入清单、定额、图纸算量...');
- AssignNode(FFirstBill, vItem);
- vNode := FFirstBill.NextSibling(FFirstBill);
- RcsvAddBills(vNode, vItem);
- end
- // 三算从第一部分开始递归
- else
- begin
- AssignNode(FFirstBill, vItem);
- vNode := FFirstBill.Elements[0];
- AddProgressForm(10, '正在导入项目节、定额、图纸算量...');
- RcsvAddBills(vNode, vItem);
- // 开始搞第二部分
- if Assigned(FSecondBill) then
- begin
- BillsTree.SelectedIndex := -1;
- AssignNode(FSecondBill, vItem2);
- vNode := FSecondBill.Elements[0];
- AddProgressForm(10, '正在导入土地...');
- RcsvAddBills(vNode, vItem2);
- end;
- if Assigned(FThirdBill) then
- begin
- BillsTree.SelectedIndex := -1;
- AssignNode(FThirdBill, vItem3);
- vNode := FThirdBill.Elements[0];
- AddProgressForm(10, '正在导入第三部分...');
- RcsvAddBills(vNode, vItem3);
- end;
- if Assigned(FFourthBill) then
- begin
- BillsTree.SelectedIndex := -1;
- AssignNode(FFourthBill, vItem4);
- vNode := FFourthBill.Elements[0];
- AddProgressForm(10, '正在导入第四部分...');
- RcsvAddBills(vNode, vItem4);
- end;
- end;
- // 标段属性
- // vNode := FRoot.FindNode('ProjectAddInfo');
- // if Assigned(vNode) then
- // LoadPropertities(vNode);
- AddProgressForm(60, '正在全局造价计算...');
- TScProject(FProject).Bills.CalculateAll;
- // 先不保存吧,万一客户操作失误,想更新却误用了导入,一保存就不能反悔了。
- // TScProjBaseData(TScProject(Project).ProjData).Save;
- finally
- FXMLNodeList.Free;
- TScProject(FProject).RealTimeCalc := OldRealTimeCalc;
- CloseProgressForm;
- Screen.Cursor := crDefault;
- end;
- end;
- procedure TtzslXMLPort.RcsvUpdateItems(AItem: TScBillsItem);
- begin
- if AItem = nil then Exit;
- UpdateItem(AItem);
- if Assigned(AItem.FirstChild) then
- RcsvUpdateItems(TScBillsItem(AItem.FirstChild));
- if Assigned(AItem.NextSibling) then
- RcsvUpdateItems(TScBillsItem(AItem.NextSibling));
- end;
- procedure TtzslXMLPort.RcsvCompareItems(AItem: TScBillsItem);
- begin
- if AItem = nil then Exit;
- CompareItem(AItem);
- if Assigned(AItem.FirstChild) then
- RcsvCompareItems(TScBillsItem(AItem.FirstChild));
- if Assigned(AItem.NextSibling) and (AItem.NextSibling.ID <> 3) then // 第三部分及以后都忽略
- RcsvCompareItems(TScBillsItem(AItem.NextSibling));
- end;
- procedure TtzslXMLPort.UpdateFromXML;
- var
- OldRealTimeCalc: Boolean;
- vNode: TXmlNode;
- vItem: TScBillsItem;
- sName: string;
- begin
- if not FileExists(FXMLFile) then Exit;
- FXMLDoc.LoadFromFile(FXMLFile);
- CheckB_CodeFieldName;
- if not CheckXMLFile then Exit;
- vItem := TScBillsItem(FBillsTree.Selected);
- sName := FFirstBill.AttributeValueByNameUTF8['Name'];
- if not ((vItem.Code = FFirstBill.AttributeValueByNameUTF8['Code'])
- and (vItem.B_Code = FFirstBill.AttributeValueByNameUTF8[FB_CodeFieldName])
- and (vItem.Name = sName))
- // and SameText(vItem.FullCode, PXMLNode(FXMLNodesList[i]).FullCode)
- then
- begin
- MessageHint(0, '操作失败,当前选中要更新的树节点跟文件的起始节点不一致!');
- Exit;
- end;
- Screen.Cursor := crHourGlass;
- CreateProgressForm(100, '从算量XML文件更新');
- OldRealTimeCalc := TScProject(FProject).RealTimeCalc;
- try
- TScProject(FProject).RealTimeCalc := False;
- // 先取XML文件中的清单,线性列表存储
- AddProgressForm(5, '正在生成映射列表...');
- AnalyzeXMLNodesIntoList(vItem);
- if FXMLNodesList.Count = 0 then Exit;
- AddProgressForm(5, '开始更新...');
- RcsvUpdateItems(vItem);
- AddProgressForm(60, '正在全局造价计算...');
- TScProject(FProject).Bills.CalculateAll;
- finally
- TScProject(FProject).RealTimeCalc := OldRealTimeCalc;
- CloseProgressForm;
- Screen.Cursor := crDefault;
- end;
- end;
- procedure TtzslXMLPort.CompareFromXML(ACDS: TClientDataSet);
- var
- OldRealTimeCalc: Boolean;
- vNode: TXmlNode;
- vItem: TScBillsItem;
- begin
- FCompareCDS := ACDS;
- FCompareCDS.First;
- while not FCompareCDS.Eof do
- FCompareCDS.Delete;
- if not FileExists(FXMLFile) then Exit;
- FXMLDoc.LoadFromFile(FXMLFile);
- CheckB_CodeFieldName;
- if not CheckXMLFile then Exit;
- vItem := TScBillsItem(FBillsTree.Selected);
- // vItem := TScBillsItem(BillsTree[idNormalBillsRoot]);
- if not (
- (vItem.Code = FFirstBill.AttributeValueByNameUTF8['Code'])
- and (vItem.B_Code = FFirstBill.AttributeValueByNameUTF8[FB_CodeFieldName])
- and (vItem.Name = FFirstBill.AttributeValueByNameUTF8['Name'])
- )
- // and SameText(vItem.FullCode, PXMLNode(FXMLNodesList[i]).FullCode)
- then
- begin
- MessageHint(0, '操作失败,当前选中要对比的节点跟XML文件不匹配!');
- Exit;
- end;
- Screen.Cursor := crHourGlass;
- CreateProgressForm(100, '从算量XML文件对比');
- try
- // 先取XML文件中的清单,线性列表存储
- AddProgressForm(5, '正在生成映射列表...');
- AnalyzeXMLNodesIntoList(vItem);
- if FXMLNodesList.Count = 0 then Exit;
- AddProgressForm(5, '开始对比...');
- // CompareItem(vItem);
- // RcsvCompareItems(TScBillsItem(vItem.FirstChild));
- RcsvCompareItems(vItem);
- CompareDeleted;
- finally
- FCompareCDS.First;
- CloseProgressForm;
- Screen.Cursor := crDefault;
- end;
- end;
- function IsCheckMatched(AXMLNode: TXmlNode; ARec: TScRationRecord): Boolean;
- var isSameAdjustState: Boolean;
- sN, sR: string;
- begin
- Result := False;
- // 判断定额调整状态
- isSameAdjustState := True;
- // if AXMLNode.HasAttribute('AdjustStr') and (AXMLNode.AttributeAdd('AdjustStr'] <> '') then
- // begin
- // // xml 多了()、尾部分号和空格
- // sN := Trim(AXMLNode.AttributeAdd('AdjustStr']);
- // sN := StringReplace(sN, '(', '', [rfReplaceAll, rfIgnoreCase]);
- // sN := StringReplace(sN, ')', '', [rfReplaceAll, rfIgnoreCase]);
- // sR := ARec.AdjustState.AsString + ';';
- // // AnsiToUtf8()
- // isSameAdjustState := (sN = sR);
- // end;
- if (AXMLNode.AttributeValueByNameUTF8['Code'] = Null) or (AXMLNode.AttributeValueByNameUTF8['Code'] = '') then
- begin
- Result := isSameAdjustState and (AXMLNode.AttributeValueByNameUTF8['Name'] = ARec.Name.AsString);
- end
- else
- begin
- Result := isSameAdjustState and (AXMLNode.AttributeValueByNameUTF8['Code'] = ARec.Code.AsString);
- end;
- end;
- function TtzslXMLPort.SameFullCode(AXMLNodeFullCode: string; AItem: TScBillsItem): Boolean;
- var sIC: string;
- begin
- sIC := GetCompareFullCode(AItem);
- // XML可以不导出父层,此时FullCode不完整,所以只能用部分匹配比较。
- Result := Pos(AXMLNodeFullCode, sIC) > 0;
- end;
- procedure TtzslXMLPort.UpdateItem(AItem: TScBillsItem);
- var i, j, k, x: Integer;
- vBNode, vRNode, vRLNode, vDQLNode: TXmlNode;
- vRationList: TList;
- vRRec: TScRationRecord;
- sBI: string;
- fValue, fValue1, fValue2: Double;
- sFCode,sName: string;
- const vArr: array[0..2] of String = ('RationList', 'MultiList', 'DeviceList');
- begin
- // if AItem.HasChildren then Exit; // 暂时只更新叶子清单,及其下定额。
- sBI := AItem.Code + ' ' + AItem.B_Code + ' ' + AItem.Name;
- AddProgressForm(1, '正在更新清单“' + sBI + '”...');
- vRationList := TList.Create;
- try
- for i := 0 to FXMLNodesList.Count - 1 do
- begin
- vBNode := PXMLNode(FXMLNodesList[i]).Data;
- sFCode := PXMLNode(FXMLNodesList[i]).FullCode;
- sName := vBNode.AttributeValueByNameUTF8['Name'];
- // 先匹配正确的清单。
- if (AItem.Code = vBNode.AttributeValueByNameUTF8['Code'])
- and (AItem.B_Code = vBNode.AttributeValueByNameUTF8[FB_CodeFieldName])
- and (AItem.Name = sName)
- and SameFullCode(sFCode, AItem) then
- begin
- // 清单
- fValue := XMLSafeDouble(vBNode.AttributeValueByNameUTF8['Quantity']);
- fValue1 := XMLSafeDouble(vBNode.AttributeValueByNameUTF8['DgnQuantity1']);
- fValue2 := XMLSafeDouble(vBNode.AttributeValueByNameUTF8['DgnQuantity2']);
- if (AItem.Rec.Quantity.AsFloat <> fValue)
- or (AItem.Rec.DesignQuantity.AsFloat <> fValue1)
- or (AItem.Rec.DesignQuantity2.AsFloat <> fValue2) then
- begin
- AItem.Rec.BeginUpdate;
- AItem.Rec.Quantity.AsVariant := fValue;
- AItem.Rec.DesignQuantity.AsVariant := fValue1;
- AItem.Rec.DesignQuantity2.AsVariant := fValue2;
- AItem.Rec.EndUpdate;
- end;
- // // 定额、量价、设备
- for x := 0 to High(vArr) do
- begin
- vRLNode := vBNode.FindNode(vArr[x]);
- if (vRLNode <> nil) and (vRLNode.ElementCount > 0) then
- begin
- TScProject(FProject).Rations.GetRations(AItem.ID, vRationList);
- for j := 0 to vRationList.Count - 1 do
- begin
- vRRec := TScRationRecord(vRationList[j]);
- AddProgressForm(1, Format('正在更新定额:%s %s(清单:%s)', [vRRec.Code.AsString, vRRec.Name.AsString, sBI]));
- for k := 0 to vRLNode.ElementCount - 1 do
- begin
- vRNode := vRLNode.Elements[k];
- if IsCheckMatched(vRNode, vRRec) then
- begin
- fValue := XMLSafeDouble(vRNode.AttributeValueByNameUTF8['Quantity']);
- if fValue <> vRRec.Quantity.AsVariant then
- begin
- vRRec.BeginUpdate;
- vRRec.Quantity.AsVariant := fValue;
- vRRec.EndUpdate;
- end;
- Break;
- end;
- end;
- end;
- end;
- end;
- // 图纸工程量
- vDQLNode := vBNode.FindNode('DrawingQuantityList');
- if (vDQLNode <> nil) and (vDQLNode.ElementCount > 0) then
- begin
- TScProject(FProject).Bills.DrawingQuantityDM.UpdateDQsByXML(AItem, vDQLNode);
- end;
- // 匹配成功,移出列表,提高后续效率
- FXMLNodesList.Delete(i);
- Break;
- end;
- end;
- finally
- vRationList.Free;
- end;
- end;
- { 算法原理: 2021.04.01 CSL
- 将XML文件中的结点抽出来,存成线性结构A。递归造价书的树结点,跟A对比:
- ① 匹配成功的,a.判断有没有修改数量。b.从A中删除,以减少后续匹配量,提高效率,
- 且为重要的第③步提供基础数据。
- ② 没匹配成功的(A中找不到),表示造价书新增了结点。
- ③ A剩余的,表示造价书中删除了。CompareDeleted()方法中处理 }
- procedure TtzslXMLPort.CompareItem(AItem: TScBillsItem);
- var i, j, k: Integer;
- vBNode, vRNode, vRLNode, vDQLNode: TXmlNode;
- vRItemList, vRNodeList: TList;
- vRRec: TScRationRecord;
- sBI, sState, sFCode: string;
- fValue, fValue1, fValue2: Double;
- isMatched, isRationMatched: Boolean;
- procedure GetXMLRations(ABNode: TXmlNode; AList: TList);
- var n, x: Integer;
- vRLNode, vCurNode: TXmlNode;
- const vArr: array[0..2] of String = ('RationList', 'MultiList', 'DeviceList');
- const vNames: array[0..2] of String = ('定额', '量价', '设备');
- begin
- while AList.Count > 0 do
- AList.Delete(0);
- for x := 0 to High(vArr) do
- begin
- vRLNode := ABNode.FindNode(vArr[x]);
- if (vRLNode <> nil) and (vRLNode.ElementCount > 0) then
- begin
- for n := 0 to vRLNode.ElementCount - 1 do
- begin
- vCurNode := vRLNode.Elements[n];
- vCurNode.AttributeAddUTF8('kind', vNames[x]);
- AList.Add(Pointer(vCurNode));
- end;
- end;
- end;
- end;
- begin
- // if AItem.HasChildren then Exit; // 暂时只更新叶子清单,及其下定额。
- sBI := AItem.Code + ' ' + AItem.B_Code + ' ' + AItem.Name;
- AddProgressForm(1, '正在对比清单“' + sBI + '”...');
- isMatched := False;
- vRItemList := TList.Create;
- vRNodeList := TList.Create;
- try
- for i := 0 to FXMLNodesList.Count - 1 do
- begin
- vBNode := PXMLNode(FXMLNodesList[i]).Data;
- sFCode := PXMLNode(FXMLNodesList[i]).FullCode;
- // 先匹配正确的清单。
- if (AItem.Code = vBNode.AttributeValueByNameUTF8['Code'])
- and (AItem.B_Code = vBNode.AttributeValueByNameUTF8[FB_CodeFieldName])
- and (AItem.Name = vBNode.AttributeValueByNameUTF8['Name'])
- and SameFullCode(sFCode, AItem) then
- begin
- // 清单
- fValue := XMLSafeDouble(vBNode.AttributeValueByNameUTF8['Quantity']);
- fValue1 := XMLSafeDouble(vBNode.AttributeValueByNameUTF8['DgnQuantity1']);
- fValue2 := XMLSafeDouble(vBNode.AttributeValueByNameUTF8['DgnQuantity2']);
- if (AItem.Rec.Quantity.AsFloat <> fValue)
- or (AItem.Rec.DesignQuantity.AsFloat <> fValue1)
- or (AItem.Rec.DesignQuantity2.AsFloat <> fValue2) then
- begin
- FCompareCDS.Append;
- FCompareCDS.FieldByName('BillID').AsInteger := AItem.ID;
- FCompareCDS.FieldByName('Operate').AsString := '修改';
- FCompareCDS.FieldByName('Kind').AsString := GetBillKindName(AItem);
- FCompareCDS.FieldByName('Code').AsString := AItem.Code + AItem.B_Code; // 合并显示
- // FCompareCDS.FieldByName('B_Code').AsString := AItem.B_Code;
- FCompareCDS.FieldByName('Name').AsString := AItem.Name;
- // 以下为三大数量变动描述
- sState := '';
- if AItem.Rec.Quantity.AsFloat <> fValue then
- // FCompareCDS.FieldByName('Quantity').AsString := Format('%g[%g]', [AItem.Rec.Quantity.AsFloat, fValue]);
- sState := Format('数量%g改%g', [fValue, AItem.Rec.Quantity.AsFloat]);
- if AItem.Rec.DesignQuantity.AsFloat <> fValue1 then
- // FCompareCDS.FieldByName('DgnQuantity1').AsString := Format('%g[%g]', [AItem.Rec.DesignQuantity.AsFloat, fValue1]);
- sState := sState + Format(',设一%g改%g', [fValue1, AItem.Rec.DesignQuantity.AsFloat]);
- if AItem.Rec.DesignQuantity2.AsFloat <> fValue2 then
- // FCompareCDS.FieldByName('DgnQuantity2').AsString := Format('%g[%g]', [AItem.Rec.DesignQuantity2.AsFloat, fValue2]);
- sState := sState + Format(',设二%g改%g', [fValue2, AItem.Rec.DesignQuantity2.AsFloat]);
- if sState <> '' then
- begin
- if Pos(',', sState) = 1 then
- Delete(sState, 1, 2);
- FCompareCDS.FieldByName('Quantity').AsString := sState;
- end;
- FCompareCDS.Post;
- end;
- // 定额对比 ↓↓↓------------------------------------------------------
- TScProject(FProject).Rations.GetRations(AItem.ID, vRItemList);
- GetXMLRations(vBNode, vRNodeList);
- for j := 0 to vRItemList.Count - 1 do
- begin
- isRationMatched := False;
- vRRec := TScRationRecord(vRItemList[j]);
- AddProgressForm(1, Format('正在更新定额:%s %s(清单:%s)', [vRRec.Code.AsString, vRRec.Name.AsString, sBI]));
- for k := 0 to vRNodeList.Count - 1 do
- begin
- vRNode := TXmlNode(vRNodeList[k]);
- // if vRNode.AttributeAdd('Code'] = vRRec.Code.AsVariant then
- if IsCheckMatched(vRNode, vRRec) then
- begin
- isRationMatched := True;
- fValue := XMLSafeDouble(vRNode.AttributeValueByNameUTF8['Quantity']);
- if fValue <> vRRec.Quantity.AsFloat then
- begin
- FCompareCDS.Append;
- FCompareCDS.FieldByName('BillID').AsInteger := AItem.ID;
- FCompareCDS.FieldByName('RationID').AsInteger := vRRec.ID.AsInteger;
- FCompareCDS.FieldByName('Operate').AsString := '修改';
- FCompareCDS.FieldByName('Kind').AsString := vRNode.AttributeValueByNameUTF8['kind'];
- FCompareCDS.FieldByName('Code').AsString := vRRec.Code.AsString;
- FCompareCDS.FieldByName('Name').AsString := vRRec.Name.AsString;
- FCompareCDS.FieldByName('Quantity').AsString := Format('工程量%g改%g', [fValue, vRRec.Quantity.AsFloat]);
- FCompareCDS.Post;
- end;
- vRNodeList.Delete(k);
- Break;
- end;
- end;
- if not isRationMatched then
- begin
- FCompareCDS.Append;
- FCompareCDS.FieldByName('BillID').AsInteger := AItem.ID;
- FCompareCDS.FieldByName('RationID').AsInteger := vRRec.ID.AsInteger;
- FCompareCDS.FieldByName('Operate').AsString := '增加';
- FCompareCDS.FieldByName('Kind').AsString := GetRationKindName(vRRec);
- FCompareCDS.FieldByName('Code').AsString := vRRec.Code.AsString;
- FCompareCDS.FieldByName('Name').AsString := vRRec.Name.AsString;
- FCompareCDS.FieldByName('Quantity').AsString := Format('工程量%g', [vRRec.Quantity.AsFloat]);
- FCompareCDS.Post;
- end;
- end;
- if vRNodeList.Count > 0 then
- begin
- for k := 0 to vRNodeList.Count - 1 do
- begin
- vRNode := TXmlNode(vRNodeList[k]);
- FCompareCDS.Append;
- FCompareCDS.FieldByName('BillID').AsInteger := AItem.ID;
- FCompareCDS.FieldByName('Operate').AsString := '删除';
- FCompareCDS.FieldByName('Kind').AsString := vRNode.AttributeValueByNameUTF8['kind'];
- FCompareCDS.FieldByName('Code').AsString := vRNode.AttributeValueByNameUTF8['Code'];
- FCompareCDS.FieldByName('Name').AsString := vRNode.AttributeValueByNameUTF8['Name'];
- FCompareCDS.FieldByName('Quantity').AsString := Format('工程量%s', [vRNode.AttributeValueByNameUTF8['Quantity']]);
- FCompareCDS.Post;
- end;
- end;
- // 定额对比 ↑↑↑------------------------------------------------------
-
- // 图纸工程量:暂不提供,先屏蔽。
- // vDQLNode := vBNode.FindNode('DrawingQuantityList');
- // if (vDQLNode <> nil) and (vDQLNode.ElementCount > 0) then
- // begin
- // TScProject(FProject).Bills.DrawingQuantityDM.CompareDQsByXML(AItem, vDQLNode, FCompareCDS);
- // end;
- // 匹配成功,移出列表,提高后续效率
- FXMLNodesList.Delete(i);
- isMatched := True;
- Break;
- end;
- end;
- if not isMatched then
- begin
- FCompareCDS.Append;
- FCompareCDS.FieldByName('BillID').AsInteger := AItem.ID;
- FCompareCDS.FieldByName('Operate').AsString := '增加';
- FCompareCDS.FieldByName('Kind').AsString := GetBillKindName(AItem);
- FCompareCDS.FieldByName('Code').AsString := AItem.Code + AItem.B_Code;
- // FCompareCDS.FieldByName('B_Code').AsString := AItem.B_Code;
- FCompareCDS.FieldByName('Name').AsString := AItem.Name;
- sState := '';
- if AItem.Rec.Quantity.AsFloat <> 0 then
- sState := Format('数量%g', [AItem.Rec.Quantity.AsFloat]);
- if AItem.Rec.DesignQuantity.AsFloat <> 0 then
- sState := sState + Format(',设一%g', [AItem.Rec.DesignQuantity.AsFloat]);
- if AItem.Rec.DesignQuantity2.AsFloat <> 0 then
- sState := sState + Format(',设二%g', [AItem.Rec.DesignQuantity2.AsFloat]);
- if Pos(',', sState) = 1 then
- Delete(sState, 1, 2);
- FCompareCDS.FieldByName('Quantity').AsString := sState;
- FCompareCDS.Post;
- end;
- finally
- vRItemList.Free;
- vRNodeList.Free;
- end;
- end;
- procedure TtzslXMLPort.CompareDeleted;
- var i: Integer;
- vBNode: TXmlNode;
- fValue, fValue1, fValue2: Double;
- sState: string;
- begin
- for i := 0 to FXMLNodesList.Count - 1 do
- begin
- vBNode := PXMLNode(FXMLNodesList[i]).Data;
- FCompareCDS.Append;
- FCompareCDS.FieldByName('Operate').AsString := '删除';
- FCompareCDS.FieldByName('Kind').AsString := GetBillKindName(vBNode);
- FCompareCDS.FieldByName('Code').AsString := vBNode.AttributeValueByNameUTF8['Code'] + vBNode.AttributeValueByNameUTF8[FB_CodeFieldName];
- FCompareCDS.FieldByName('Name').AsString := vBNode.AttributeValueByNameUTF8['Name'];
- fValue := XMLSafeDouble(vBNode.AttributeValueByNameUTF8['Quantity']);
- fValue1 := XMLSafeDouble(vBNode.AttributeValueByNameUTF8['DgnQuantity1']);
- fValue2 := XMLSafeDouble(vBNode.AttributeValueByNameUTF8['DgnQuantity2']);
- sState := '';
- if fValue <> 0 then
- sState := Format('数量%g', [fValue]);
- if fValue1 <> 0 then
- sState := sState + Format(',设一%g', [fValue1]);
- if fValue2 <> 0 then
- sState := sState + Format(',设二%g', [fValue2]);
- if Pos(',', sState) = 1 then
- Delete(sState, 1, 2);
- FCompareCDS.FieldByName('Quantity').AsString := sState;
- FCompareCDS.Post;
- end;
- end;
- function TtzslXMLPort.GetBillKindName(AItem: TScBillsItem): string;
- begin
- if AItem.B_Code <> '' then
- Result := '清单'
- else
- Result := '分项';
- end;
- function TtzslXMLPort.GetBillKindName(ANode: TXmlNode): string;
- begin
- if ANode.HasAttribute(FB_CodeFieldName) and (ANode.AttributeValueByNameUTF8[FB_CodeFieldName] <> '') then
- Result := '清单'
- else
- Result := '分项';
- end;
- procedure TtzslXMLPort.AssignNode(ANode: TXmlNode; AItem: TScBillsItem);
- begin
- with AItem.Rec do
- begin
- BeginUpdate;
- if FIsBills then
- Code.AsVariant := XMLSafeVariant(ANode.AttributeValueByNameUTF8[FB_CodeFieldName])
- else
- begin
- Code.AsVariant := XMLSafeVariant(ANode.AttributeValueByNameUTF8['Code']);
- B_Code.AsVariant := XMLSafeVariant(ANode.AttributeValueByNameUTF8[FB_CodeFieldName]);
- end;
- Name.AsVariant := XMLSafeVariant(ANode.AttributeValueByNameUTF8['Name']);
- Units.AsVariant := XMLSafeVariant(ANode.AttributeValueByNameUTF8['Units']);
- Quantity.AsVariant := XMLSafeVariant(ANode.AttributeValueByNameUTF8['Quantity']);
- DesignQuantity.AsVariant := XMLSafeVariant(ANode.AttributeValueByNameUTF8['DgnQuantity1']);
- DesignQuantity2.AsVariant := XMLSafeVariant(ANode.AttributeValueByNameUTF8['DgnQuantity2']);
- // 下面这三项有值时,导不进来。
- // UnitPrice.AsVariant := ANode.AttributeValueByName['UnitPrice'];
- // DesignPrice.AsVariant := ANode.AttributeValueByName['DgnPrice'];
- // TotalPrice.AsVariant := ANode.AttributeValueByName['TotalPrice'];
- MemoStr.AsVariant := XMLSafeVariant(ANode.AttributeValueByNameUTF8['MemoStr']);
- IsCreatePriceAnalysis.AsVariant := XMLSafeVariant(ANode.AttributeValueByNameUTF8['IsCreatePriceAnalysis']);
- IsQDYS.AsVariant := XMLSafeVariant(ANode.AttributeValueByNameUTF8['IsQDYS']);
- if ANode.HasAttribute('InterimType') and (ANode.AttributeValueByNameUTF8['InterimType'] <> '') then // Excel 即使导出无值,导入时也有属性,值为''
- begin
- IsSpecialInterim.AsBoolean := True;
- InterimType.AsVariant := XMLSafeVariant(ANode.AttributeValueByNameUTF8['InterimType']);
- end;
- EndUpdate;
- end;
- end;
- procedure TtzslXMLPort.AddRations(ANode: TXmlNode; AItem: TScBillsItem; var ASerialNo: Integer);
- var vRL: TXmlNode;
- begin
- vRL := ANode.FindNode('RationList');
- if vRL = nil then Exit;
- TScProject(FProject).Rations.AddRationsFromXML(AItem, vRL, ASerialNo);
- end;
- procedure TtzslXMLPort.AddCountPrice(ANode: TXmlNode; AItem: TScBillsItem; ASerialNo: Integer);
- var vRL: TXmlNode;
- begin
- vRL := ANode.FindNode('MultiList');
- if vRL = nil then Exit;
- TScProject(FProject).Rations.AddCountPriceFromXML(AItem, vRL, False, ASerialNo);
- end;
- procedure TtzslXMLPort.AddEquipment(ANode: TXmlNode; AItem: TScBillsItem);
- var vRL: TXmlNode;
- begin
- vRL := ANode.FindNode('DeviceList');
- if vRL = nil then Exit;
- TScProject(FProject).Rations.AddEquipmentFromXML(AItem, vRL);
- end;
- procedure TtzslXMLPort.AddDQs(ANode: TXmlNode; AItem: TScBillsItem);
- var vDQL: TXmlNode;
- begin
- vDQL := ANode.FindNode('DrawingQuantityList');
- if vDQL = nil then Exit;
- TScProject(FProject).Bills.DrawingQuantityDM.AddDrawingQuantityFromXML(AItem, vDQL);
- end;
- procedure TtzslXMLPort.AddGroundCompensate(ANode: TXmlNode; AItem: TScBillsItem);
- var vGC: TXmlNode;
- begin
- vGC := ANode.FindNode('Ground');
- if not Assigned(vGC) then Exit;
- BillsTree.SelectedIndex := BillsTree.IndexOf(AItem);
- TScProject(FProject).LeafTreesDM.TreeManager.AddLeafTreeFromXML(FProject, AItem, vGC);
- end;
- procedure TtzslXMLPort.RcsvAddBills(ANode: TXmlNode; AParentItem: TScBillsItem);
- function CodeFieldName: string;
- begin
- if FIsBills then
- Result := FB_CodeFieldName
- else
- Result := 'Code';
- end;
- function NodeLevel(ACode: string): Integer;
- var
- iPos: Integer;
- strTemp: string;
- begin
- Result := 0;
- strTemp := ACode;
- repeat
- iPos := Pos('-', strTemp);
- if iPos > 0 then
- begin
- Inc(Result);
- strTemp := Copy(strTemp, iPos + 1, Length(strTemp) - iPos);
- end;
- until iPos <= 0;
- end;
- function CutLastPart(ACode: string): string;
- var
- I: Integer;
- begin
- Result := '';
- for I := Length(ACode) downto 1 do
- if SameText(ACode[I], '-') then
- begin
- Result := Copy(ACode, 1, I - 1);
- Break;
- end;
- end;
- function InChapter(AChapterName, AChildCode: string): Boolean;
- var
- iPosDi, iChapterNum, iChildNum: Integer;
- chChapter, chChild: Char;
- begin
- Result := False;
- if (AChapterName = '') or (AChildCode = '') then Exit;
- iPosDi := Pos('第', AChapterName);
- if (iPosDi <= 0) and (Pos('00章', AChapterName) <= 0) then
- Exit;
- chChapter := AChapterName[iPosDi + 2];
- chChild := AChildCode[1];
- Result := (chChapter in ['1'..'9']) and (chChild in ['1'..'9']) and (chChapter = chChild);
- end;
- function IsChapter(AChapterName: string): Boolean;
- begin
- Result := (Pos('第', AChapterName) > 0) and (Pos('00章', AChapterName) > 0);
- end;
- function GetFirstChild: TXmlNode;
- var
- NextNode: TXmlNode;
- strCode, strName, strNextCode: string;
- begin
- Result := nil;
- NextNode := ANode.NextSibling(ANode);
- if NextNode = nil then Exit;
- strCode := ANode.AttributeValueByNameUTF8[CodeFieldName];
- strName := ANode.AttributeValueByNameUTF8['Name'];
- strNextCode := NextNode.AttributeValueByNameUTF8[CodeFieldName];
- // 101 -> 101-1 或 第100章 -> 101
- if ((strCode <> '') and SameText(strCode, CutLastPart(strNextCode))) or InChapter(strName, strNextCode) then
- begin
- Result := NextNode;
- FXMLNodeList.Add(TXMLNode(Result));
- end;
- end;
- function GetNextSibling: TXmlNode;
- var
- NextNode: TXmlNode;
- strCode, strName, strNextCode, strNextName: string;
- begin
- Result := nil;
- NextNode := ANode.NextSibling(ANode);
- while NextNode <> nil do
- begin
- // 已加过的节点Continue
- if FXMLNodeList.IndexOf(TXMLNode(NextNode)) >= 0 then
- begin
- NextNode := NextNode.NextSibling(NextNode);
- Continue;
- end;
- strCode := ANode.AttributeValueByNameUTF8[CodeFieldName];
- strName := ANode.AttributeValueByNameUTF8['Name'];
- strNextCode := NextNode.AttributeValueByNameUTF8[CodeFieldName];
- strNextName := NextNode.AttributeValueByNameUTF8['Name'];
- //if (strCode='502') and (strNextCode='503') then
- // MessageHint(Format('Code: %s, %s; level: %d, %d; p: %s, %s', [strCode, strNextCode, NodeLevel(strCode), NodeLevel(strNextCode), CutLastPart(strCode), CutLastPart(strNextCode)]));
- // 101 -> 102 // 层次相同 // 编号前面部分相同
- //if ((strCode <> '') and (strNextCode <> '') and (NodeLevel(strCode) = NodeLevel(strNextCode)) and SameText(CutLastPart(strCode), CutLastPart(strNextCode)))
- // 遇到另一章中止
- if (strCode <> '') and (strNextCode = '') and IsChapter(strNextName) then
- Break;
- // 101 -> 102
- if ((strCode <> '') and (strNextCode <> '') and (SameText(AParentItem.Code, CutLastPart(strNextCode)) // 是否同父节点
- or (IsChapter(AParentItem.Name) and InChapter(AParentItem.Name, strNextCode)))) // 全国清单缺中间层次节点,底层直接挂在章节点下
- or (IsChapter(strName) and IsChapter(strNextName)) then //或 第100章 -> 第200章
- begin
- Result := NextNode;
- FXMLNodeList.Add(TXMLNode(Result));
- Break;
- end;
- NextNode := NextNode.NextSibling(NextNode);
- end;
- end;
- var
- vItem: TScBillsItem;
- iID, iSN: Integer;
- sCode, sName: string;
- firstNode, ChildNode, NextSiblingNode: TXmlNode;
- begin
- if ANode = nil then Exit;
- if ANode.Name <> 'Bills' then Exit;
- iID := -1;
- if (ANode.AttributeValueByNameUTF8[CodeFieldName] <> '') then
- begin
- sCode := ANode.AttributeValueByNameUTF8[CodeFieldName];
- sName := ANode.AttributeValueByNameUTF8['Name'];
- if (sCode = '110') then iID := idSpecifyFee
- else if (sCode = '11001') then iID := idSiteConstructItem
- else if (sCode = '11002') then iID := idSafeProduction
- // 土地部分
- else if ((sCode = '20101') and (sName = '永久征用土地')) then iID := idGroundCompensate
- else if ((sCode = '20102') and (sName = '临时用地')) then iID := idGroundTemporary
- else if ((sCode = '202') and (sName = '拆迁补偿费')) then iID := idGroundRemove;
- end;
- if (iID <> -1) then
- vItem := BillsTree.AddBillsItem(iID, AParentItem.ID, -1)
- else
- vItem := BillsTree.AddBillsItem(AParentItem.ID, -1);
- AssignNode(ANode, vItem);
- AddProgressForm(1, Format('正在导入清单:%s %s %s', [vItem.Code, vItem.B_Code, vItem.Name]));
- iSN := 1;
- AddRations(ANode, vItem, iSN);
- AddCountPrice(ANode, vItem, iSN); // 导入量价
- AddEquipment(ANode, vItem); // 导入设备
- AddDQs(ANode, vItem);
- AddGroundCompensate(ANode, vItem); // 导入土地
- // 算量导出的清单类型xml全部是平级,所以要特殊处理
- if FIsBills then
- begin
- ChildNode := GetFirstChild;
- if ChildNode <> nil then
- RcsvAddBills(ChildNode, vItem);
- NextSiblingNode := GetNextSibling;
- if NextSiblingNode <> nil then
- RcsvAddBills(NextSiblingNode, AParentItem);
- end
- else
- begin
- // 当父清单有子结点<DrawingQuantityList>、<Bills>时,第一孩子不符合条件退出,导致后兄弟<Bills>无法导入。此时第一孩子老大不行应换老二来。
- firstNode := ANode.Elements[0];
- if Assigned(firstNode) then
- begin
- if (firstNode.Name = 'DrawingQuantityList') then
- RcsvAddBills(firstNode.NextSibling(firstNode), vItem)
- else
- RcsvAddBills(firstNode, vItem);
- end;
- if Assigned(ANode.NextSibling(ANode)) then
- RcsvAddBills(ANode.NextSibling(ANode), AParentItem);
- end;
- end;
- function TtzslXMLPort.GetRationKindName(ARec: TScRationRecord): string;
- begin
- if ARec.IsMECalc.AsBoolean then
- Result := '设备'
- else if ARec.RationType.AsInteger = 1 then
- Result := '量价'
- else
- Result := '定额';
- end;
- { TExcelToXMLPort }
- function TExcelBlockXMLPort.CheckXMLFile: Boolean;
- var
- sType: string;
- iProjType: Integer;
- begin
- FInfo := FRoot.FindNode('Info');
- FBillList := FRoot.FindNode('BillList');
- FFirstBill := FBillList.Elements[0];
- Result := True;
- end;
- procedure TExcelBlockXMLPort.LoadFromXML;
- var
- OldRealTimeCalc: Boolean;
- vItem, vFirstChildItem, curItem: TScBillsItem;
- sFile: string;
- eaSL: TStringList;
- curNode: TXmlNode;
- i: Integer;
- begin
- if not FileExists(FXMLFile) then Exit;
- FXMLDoc.LoadFromFile(FXMLFile);
- CheckB_CodeFieldName;
- CheckXMLFile;
- Screen.Cursor := crHourGlass;
- CreateProgressForm(100, '导入Excel块文件');
- OldRealTimeCalc := TScProject(FProject).RealTimeCalc;
- eaSL := TScProject(FProject).Rations.RAdjusts.ErrorAdjustList;
- eaSL.Clear;
- try
- TScProject(FProject).RealTimeCalc := False;
- vItem := TScBillsItem(BillsTree.Selected); // (选择位置后)新插入的空行
- AddProgressForm(10, '正在导入清单、定额、图纸算量...');
- RcsvAddBills(FFirstBill, vItem);
- // 修正树结构:上述操作后,所有项变成空行的子项。这些子项全部要先升级(从最后一个子结点开始)。
- for i := vItem.ChildCount - 1 downto 0 do
- begin
- curItem := TScBillsItem(vItem.ChildNodes[i]);
- curItem.UpLevel;
- end;
- // 再删除空行
- BillsTree.DeleteNode(vItem);
- AddProgressForm(60, '正在全局造价计算...');
- TScProject(FProject).Bills.CalculateAll;
- if eaSL.Count > 0 then
- begin
- MessageWarning(0, Format('Excel块导入完成,但有%d条定额的调整状态来自旧版本,无法识别,请手工调整。',[eaSL.Count]));
- sFile := ExtractFilePath(Application.ExeName) + '\UserData\导入Excel块调整失败定额.txt';
- eaSL.SaveToFile(sFile);
- ShellExecute(Application.Handle, 'open', PChar('NOTEPAD.EXE'), PChar(sFile), nil, SW_SHOW);
- end;
- finally
- eaSL.Clear;
- TScProject(FProject).RealTimeCalc := OldRealTimeCalc;
- CloseProgressForm;
- Screen.Cursor := crDefault;
- end;
- end;
- end.
|