diff --git a/DB Supervisor Manager.xml b/DB Supervisor Manager.xml
new file mode 100644
index 0000000..6e5a05f
--- /dev/null
+++ b/DB Supervisor Manager.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+ false
+
+
+
+
+ true
+
+ 1000100110021003100410051006100710321033103410351048104910501051105210531054105510801081108230083009302432483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346335683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361540084009404840494050405140524080424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415500050015002500350085009501050115012501517117117117117117117117117117117117117117117117117117117117117117117137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137137147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147147110171101711017110171101711017110171101711017110171000000004444666666661010101133131313131313131323232323232323233333333333333333434343434343434353535353535353536363636363636363737373737373737383838383838383839393939393939394040404040404040414141414141414142424242424242424343434343434343444444444444444445454545454545454646464646464646474747474747474748484848484848484949494949494949505050505050505051515151515151515252525252525252535353535353535354545454545454545555555555555555565656565656565657575757575757577171717171717171727272727272727273737373737373737474747474747474757575757575757574747474747474741166666103131313131313131323232323232323233333333333333333434343434343434353535353535353536363636363636363737373737373737383838383838383839393939393939394040404040404040414141414141414142424242424242424343434343434343444444444444444445454545454545454646464646464646474747474747474748484848484848484949494949494949505050505050505051515151515151511212121213131313131316#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0016#0116#0016#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0016#0116#0216#0316#0416#0016#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0416#0516#0616#0716#0016#0116#0216#0316#0016#0116#0216#0316#0416#0716#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#0016#00TRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUETRUEFALSEFALSETRUETRUEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSETRUEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSEFALSE171/00/0 General - General Alarm171/00/1 General - Emergency Pilz Reset KA250C1171/00/2 General - Emergency PB Pressed Main Cabinet171/00/3 General - Emergency PB Pressed X1-M31171/00/4 General - Emergency PB Pressed X1-M33171/00/5 General - Emergency PB Pressed X1-M35171/00/6 General - Emergency PB Pressed X1-M71171/00/7 General - Emergency PB Pressed X1-M75171/04/0 General - 24Vdc +A Alarm171/04/1 General - 24Vdc +B Alarm171/04/2 General - 24Vdc +CH Alarm171/04/3 General - 24Vdc +D Alarm171/06/0 General - 24Vdc +Z1 Alarm171/06/1 General - 24Vdc +Z2 Alarm171/06/2 General - 24Vdc +Z3 Alarm171/06/3 General - 24Vdc +Z4 Alarm171/06/4 General - 24Vdc +Z5 Alarm171/06/5 General - 24Vdc +Z6 Alarm171/06/6 General - 24Vdc +Z7 Alarm171/06/7 General - 24Vdc +Z8 Alarm171/10/0 General - Air Cooler Alarm171/10/1 General - UPS in Running171/10/2 General - UPS Alarm371/01/0 TableTop - ThermoMagnetic Swich Tripped371/01/1 TableTop - Trip VFD371/03/0 TableTop - ThermoMagnetic Swich Sprider Tripped [M281 -> M286]371/31/0 TableTop - M31 - ThermoMagnetic Swich Tripped371/31/1 TableTop - M31 - Trip VFD371/31/2 TableTop - M31 - DP Alarm371/31/3 TableTop - M31 - Disconnector Switch Open371/31/4 TableTop - M31 - Manual Mode371/31/5 TableTop - M31 - Power OFF371/31/6 TableTop - M31 -371/31/7 TableTop - M31 -371/32/0 TableTop - M32 - ThermoMagnetic Swich Tripped371/32/1 TableTop - M32 - Trip VFD371/32/2 TableTop - M32 - DP Alarm371/32/3 TableTop - M32 - Disconnector Switch Open371/32/4 TableTop - M32 - Manual Mode371/32/5 TableTop - M32 - Power OFF371/32/6 TableTop - M32 -371/32/7 TableTop - M32 -371/33/0 TableTop - M33 - ThermoMagnetic Swich Tripped371/33/1 TableTop - M33 - Trip VFD371/33/2 TableTop - M33 - DP Alarm371/33/3 TableTop - M33 - Disconnector Switch Open371/33/4 TableTop - M33 - Manual Mode371/33/5 TableTop - M33 - Power OFF371/33/6 TableTop - M33 -371/33/7 TableTop - M33 -371/34/0 TableTop - M34 - ThermoMagnetic Swich Tripped371/34/1 TableTop - M34 - Trip VFD371/34/2 TableTop - M34 - DP Alarm371/34/3 TableTop - M34 - Disconnector Switch Open371/34/4 TableTop - M34 - Manual Mode371/34/5 TableTop - M34 - Power OFF371/34/6 TableTop - M34 -371/34/7 TableTop - M34 -371/35/0 TableTop - M35 - ThermoMagnetic Swich Tripped371/35/1 TableTop - M35 - Trip VFD371/35/2 TableTop - M35 - DP Alarm371/35/3 TableTop - M35 - Disconnector Switch Open371/35/4 TableTop - M35 - Manual Mode371/35/5 TableTop - M35 - Power OFF371/35/6 TableTop - M35 -371/35/7 TableTop - M35 -371/36/0 TableTop - M36 - ThermoMagnetic Swich Tripped371/36/1 TableTop - M36 - Trip VFD371/36/2 TableTop - M36 - DP Alarm371/36/3 TableTop - M36 - Disconnector Switch Open371/36/4 TableTop - M36 - Manual Mode371/36/5 TableTop - M36 - Power OFF371/36/6 TableTop - M36 -371/36/7 TableTop - M36 -371/37/0 TableTop - M37 - ThermoMagnetic Swich Tripped371/37/1 TableTop - M37 - Trip VFD371/37/2 TableTop - M37 - DP Alarm371/37/3 TableTop - M37 - Disconnector Switch Open371/37/4 TableTop - M37 - Manual Mode371/37/5 TableTop - M37 - Power OFF371/37/6 TableTop - M37 -371/37/7 TableTop - M37 -371/38/0 TableTop - M38 - ThermoMagnetic Swich Tripped371/38/1 TableTop - M38 - Trip VFD371/38/2 TableTop - M38 - DP Alarm371/38/3 TableTop - M38 - Disconnector Switch Open371/38/4 TableTop - M38 - Manual Mode371/38/5 TableTop - M38 - Power OFF371/38/6 TableTop - M38 -371/38/7 TableTop - M38 -371/39/0 TableTop - M39 - ThermoMagnetic Swich Tripped371/39/1 TableTop - M39 - Trip VFD371/39/2 TableTop - M39 - DP Alarm371/39/3 TableTop - M39 - Disconnector Switch Open371/39/4 TableTop - M39 - Manual Mode371/39/5 TableTop - M39 - Power OFF371/39/6 TableTop - M39 -371/39/7 TableTop - M39 -371/40/0 TableTop - M40 - ThermoMagnetic Swich Tripped371/40/1 TableTop - M40 - Trip VFD371/40/2 TableTop - M40 - DP Alarm371/40/3 TableTop - M40 - Disconnector Switch Open371/40/4 TableTop - M40 - Manual Mode371/40/5 TableTop - M40 - Power OFF371/40/6 TableTop - M40 -371/40/7 TableTop - M40 -371/41/0 TableTop - M41 - ThermoMagnetic Swich Tripped371/41/1 TableTop - M41 - Trip VFD371/41/2 TableTop - M41 - DP Alarm371/41/3 TableTop - M41 - Disconnector Switch Open371/41/4 TableTop - M41 - Manual Mode371/41/5 TableTop - M41 - Power OFF371/41/6 TableTop - M41 -371/41/7 TableTop - M41 -371/42/0 TableTop - M42 - ThermoMagnetic Swich Tripped371/42/1 TableTop - M42 - Trip VFD371/42/2 TableTop - M42 - DP Alarm371/42/3 TableTop - M42 - Disconnector Switch Open371/42/4 TableTop - M42 - Manual Mode371/42/5 TableTop - M42 - Power OFF371/42/6 TableTop - M42 -371/42/7 TableTop - M42 -371/43/0 TableTop - M43 - ThermoMagnetic Swich Tripped371/43/1 TableTop - M43 - Trip VFD371/43/2 TableTop - M43 - DP Alarm371/43/3 TableTop - M43 - Disconnector Switch Open371/43/4 TableTop - M43 - Manual Mode371/43/5 TableTop - M43 - Power OFF371/43/6 TableTop - M43 -371/43/7 TableTop - M43 -371/44/0 TableTop - M44 - ThermoMagnetic Swich Tripped371/44/1 TableTop - M44 - Trip VFD371/44/2 TableTop - M44 - DP Alarm371/44/3 TableTop - M44 - Disconnector Switch Open371/44/4 TableTop - M44 - Manual Mode371/44/5 TableTop - M44 - Power OFF371/44/6 TableTop - M44 -371/44/7 TableTop - M44 -371/45/0 TableTop - M45 - ThermoMagnetic Swich Tripped371/45/1 TableTop - M45 - Trip VFD371/45/2 TableTop - M45 - DP Alarm371/45/3 TableTop - M45 - Disconnector Switch Open371/45/4 TableTop - M45 - Manual Mode371/45/5 TableTop - M45 - Power OFF371/45/6 TableTop - M45 -371/45/7 TableTop - M45 -371/46/0 TableTop - M46 - ThermoMagnetic Swich Tripped371/46/1 TableTop - M46 - Trip VFD371/46/2 TableTop - M46 - DP Alarm371/46/3 TableTop - M46 - Disconnector Switch Open371/46/4 TableTop - M46 - Manual Mode371/46/5 TableTop - M46 - Power OFF371/46/6 TableTop - M46 -371/46/7 TableTop - M46 -371/47/0 TableTop - M47 - ThermoMagnetic Swich Tripped371/47/1 TableTop - M47 - Trip VFD371/47/2 TableTop - M47 - DP Alarm371/47/3 TableTop - M47 - Disconnector Switch Open371/47/4 TableTop - M47 - Manual Mode371/47/5 TableTop - M47 - Power OFF371/47/6 TableTop - M47 -371/47/7 TableTop - M47 -371/48/0 TableTop - M48 - ThermoMagnetic Swich Tripped371/48/1 TableTop - M48 - Trip VFD371/48/2 TableTop - M48 - DP Alarm371/48/3 TableTop - M48 - Disconnector Switch Open371/48/4 TableTop - M48 - Manual Mode371/48/5 TableTop - M48 - Power OFF371/48/6 TableTop - M48 -371/48/7 TableTop - M48 -371/49/0 TableTop - M49 - ThermoMagnetic Swich Tripped371/49/1 TableTop - M49 - Trip VFD371/49/2 TableTop - M49 - DP Alarm371/49/3 TableTop - M49 - Disconnector Switch Open371/49/4 TableTop - M49 - Manual Mode371/49/5 TableTop - M49 - Power OFF371/49/6 TableTop - M49 -371/49/7 TableTop - M49 -371/50/0 TableTop - M50 - ThermoMagnetic Swich Tripped371/50/1 TableTop - M50 - Trip VFD371/50/2 TableTop - M50 - DP Alarm371/50/3 TableTop - M50 - Disconnector Switch Open371/50/4 TableTop - M50 - Manual Mode371/50/5 TableTop - M50 - Power OFF371/50/6 TableTop - M50 -371/50/7 TableTop - M50 -371/51/0 TableTop - M51 - ThermoMagnetic Swich Tripped371/51/1 TableTop - M51 - Trip VFD371/51/2 TableTop - M51 - DP Alarm371/51/3 TableTop - M51 - Disconnector Switch Open371/51/4 TableTop - M51 - Manual Mode371/51/5 TableTop - M51 - Power OFF371/51/6 TableTop - M51 -371/51/7 TableTop - M51 -371/52/0 TableTop - M52 - ThermoMagnetic Swich Tripped371/52/1 TableTop - M52 - Trip VFD371/52/2 TableTop - M52 - DP Alarm371/52/3 TableTop - M52 - Disconnector Switch Open371/52/4 TableTop - M52 - Manual Mode371/52/5 TableTop - M52 - Power OFF371/52/6 TableTop - M52 -371/52/7 TableTop - M52 -371/53/0 TableTop - M53 - ThermoMagnetic Swich Tripped371/53/1 TableTop - M53 - Trip VFD371/53/2 TableTop - M53 - DP Alarm371/53/3 TableTop - M53 - Disconnector Switch Open371/53/4 TableTop - M53 - Manual Mode371/53/5 TableTop - M53 - Power OFF371/53/6 TableTop - M53 -371/53/7 TableTop - M53 -371/54/0 TableTop - M54 - ThermoMagnetic Swich Tripped371/54/1 TableTop - M54 - Trip VFD371/54/2 TableTop - M54 - DP Alarm371/54/3 TableTop - M54 - Disconnector Switch Open371/54/4 TableTop - M54 - Manual Mode371/54/5 TableTop - M54 - Power OFF371/54/6 TableTop - M54 -371/54/7 TableTop - M54 -371/55/0 TableTop - M55 - ThermoMagnetic Swich Tripped371/55/1 TableTop - M55 - Trip VFD371/55/2 TableTop - M55 - DP Alarm371/55/3 TableTop - M55 - Disconnector Switch Open371/55/4 TableTop - M55 - Manual Mode371/55/5 TableTop - M55 - Power OFF371/55/6 TableTop - M55 -371/55/7 TableTop - M55 -371/56/0 TableTop - M56 - ThermoMagnetic Swich Tripped371/56/1 TableTop - M56 - Trip VFD371/56/2 TableTop - M56 - DP Alarm371/56/3 TableTop - M56 - Disconnector Switch Open371/56/4 TableTop - M56 - Manual Mode371/56/5 TableTop - M56 - Power OFF371/56/6 TableTop - M56 -371/56/7 TableTop - M56 -371/57/0 TableTop - M57 - ThermoMagnetic Swich Tripped371/57/1 TableTop - M57 - Trip VFD371/57/2 TableTop - M57 - DP Alarm371/57/3 TableTop - M57 - Disconnector Switch Open371/57/4 TableTop - M57 - Manual Mode371/57/5 TableTop - M57 - Power OFF371/57/6 TableTop - M57 -371/57/7 TableTop - M57 -371/71/0 TableTop - M281 - ThermoMagnetic Swich Tripped371/71/1 TableTop - M281 - Trip VFD371/71/2 TableTop - M281 - DP Alarm371/71/3 TableTop - M281 - Disconnector Switch Open371/71/4 TableTop - M281 - Manual Mode371/71/5 TableTop - M281 - Power OFF371/71/6 TableTop - M281 -371/71/7 TableTop - M281 -371/72/0 TableTop - M282 - ThermoMagnetic Swich Tripped371/72/1 TableTop - M282 - Trip VFD371/72/2 TableTop - M282 - DP Alarm371/72/3 TableTop - M282 - Disconnector Switch Open371/72/4 TableTop - M282 - Manual Mode371/72/5 TableTop - M282 - Power OFF371/72/6 TableTop - M282 -371/72/7 TableTop - M282 -371/73/0 TableTop - M283 - ThermoMagnetic Swich Tripped371/73/1 TableTop - M283 - Trip VFD371/73/2 TableTop - M283 - DP Alarm371/73/3 TableTop - M283 - Disconnector Switch Open371/73/4 TableTop - M283 - Manual Mode371/73/5 TableTop - M283 - Power OFF371/73/6 TableTop - M283 -371/73/7 TableTop - M283 -371/74/0 TableTop - M284 - ThermoMagnetic Swich Tripped371/74/1 TableTop - M284 - Trip VFD371/74/2 TableTop - M284 - DP Alarm371/74/3 TableTop - M284 - Disconnector Switch Open371/74/4 TableTop - M284 - Manual Mode371/74/5 TableTop - M284 - Power OFF371/74/6 TableTop - M284 -371/74/7 TableTop - M284 -371/75/0 TableTop - M285 - ThermoMagnetic Swich Tripped371/75/1 TableTop - M285 - Trip VFD371/75/2 TableTop - M285 - DP Alarm371/75/3 TableTop - M285 - Disconnector Switch Open371/75/4 TableTop - M285 - Manual Mode371/75/5 TableTop - M285 - Power OFF371/75/6 TableTop - M285 -371/75/7 TableTop - M285 -371/74/0 TableTop - M286 - ThermoMagnetic Swich Tripped371/74/1 TableTop - M286 - Trip VFD371/74/2 TableTop - M286 - DP Alarm371/74/3 TableTop - M286 - Disconnector Switch Open371/74/4 TableTop - M286 - Manual Mode371/74/5 TableTop - M286 - Power OFF371/74/6 TableTop - M286 -371/74/7 TableTop - M286 -471/01/0 Pack - ThermoMagnetic Swich Tripped471/01/1 Pack - Trip VFD471/06/0 Pack Divider - Porte aperte471/06/1 Pack Divider - Mancanza Aria471/06/2 Pack Divider - Controllo Sagoma471/06/3 Pack Divider - Inciampo PH Uscita471/06/4 Pack Divider - Encoder Pulse Error471/10/0 Pack - Jamming M71471/31/0 Pack - M71 - ThermoMagnetic Swich Tripped471/31/1 Pack - M71 - Trip VFD471/31/2 Pack - M71 - DP Alarm471/31/3 Pack - M71 - Disconnector Switch Open471/31/4 Pack - M71 - Manual Mode471/31/5 Pack - M71 - Power OFF471/31/6 Pack - M71 -471/31/7 Pack - M71 -471/32/0 Pack - M72 - Trip Thermic471/32/1 Pack - M72 - Trip VFD471/32/2 Pack - M72 - DP Alarm471/32/3 Pack - M72 - Disconnector Switch Open471/32/4 Pack - M72 - Manual Mode471/32/5 Pack - M72 - Power OFF471/32/6 Pack - M72 -471/32/7 Pack - M72 -471/33/0 Pack - M73 - ThermoMagnetic Swich Tripped471/33/1 Pack - M73 - Trip VFD471/33/2 Pack - M73 - DP Alarm471/33/3 Pack - M73 - Disconnector Switch Open471/33/4 Pack - M73 - Manual Mode471/33/5 Pack - M73 - Power OFF471/33/6 Pack - M73 -471/33/7 Pack - M73 -471/34/0 Pack - M74 - ThermoMagnetic Swich Tripped471/34/1 Pack - M74 - Trip VFD471/34/2 Pack - M74 - DP Alarm471/34/3 Pack - M74 - Disconnector Switch Open471/34/4 Pack - M74 - Manual Mode471/34/5 Pack - M74 - Power OFF471/34/6 Pack - M74 -471/34/7 Pack - M74 -471/35/0 Pack - M75 - ThermoMagnetic Swich Tripped471/35/1 Pack - M75 - Trip VFD471/35/2 Pack - M75 - DP Alarm471/35/3 Pack - M75 - Disconnector Switch Open471/35/4 Pack - M75 - Manual Mode471/35/5 Pack - M75 - Power OFF471/35/6 Pack - M75 -471/35/7 Pack - M75 -471/36/0 Pack - M76 - ThermoMagnetic Swich Tripped471/36/1 Pack - M76 - Trip VFD471/36/2 Pack - M76 - DP Alarm471/36/3 Pack - M76 - Disconnector Switch Open471/36/4 Pack - M76 - Manual Mode471/36/5 Pack - M76 - Power OFF471/36/6 Pack - M76 -471/36/7 Pack - M76 -471/37/0 Pack - M77 - ThermoMagnetic Swich Tripped471/37/1 Pack - M77 - Trip VFD471/37/2 Pack - M77 - DP Alarm471/37/3 Pack - M77 - Disconnector Switch Open471/37/4 Pack - M77 - Manual Mode471/37/5 Pack - M77 - Power OFF471/37/6 Pack - M77 -471/37/7 Pack - M77 -471/38/0 Pack - M78 - ThermoMagnetic Swich Tripped471/38/1 Pack - M78 - Trip VFD471/38/2 Pack - M78 - DP Alarm471/38/3 Pack - M78 - Disconnector Switch Open471/38/4 Pack - M78 - Manual Mode471/38/5 Pack - M78 - Power OFF471/38/6 Pack - M78 -471/38/7 Pack - M78 -471/39/0 Pack - M79 - ThermoMagnetic Swich Tripped471/39/1 Pack - M79 - Trip VFD471/39/2 Pack - M79 - DP Alarm471/39/3 Pack - M79 - Disconnector Switch Open471/39/4 Pack - M79 - Manual Mode471/39/5 Pack - M79 - Power OFF471/39/6 Pack - M79 -471/39/7 Pack - M79 -471/40/0 Pack - M80 - ThermoMagnetic Swich Tripped471/40/1 Pack - M80 - Trip VFD471/40/2 Pack - M80 - DP Alarm471/40/3 Pack - M80 - Disconnector Switch Open471/40/4 Pack - M80 - Manual Mode471/40/5 Pack - M80 - Power OFF471/40/6 Pack - M80 -471/40/7 Pack - M80 -471/41/0 Pack - M81 - ThermoMagnetic Swich Tripped471/41/1 Pack - M81 - Trip VFD471/41/2 Pack - M81 - DP Alarm471/41/3 Pack - M81 - Disconnector Switch Open471/41/4 Pack - M81 - Manual Mode471/41/5 Pack - M81 - Power OFF471/41/6 Pack - M81 -471/41/7 Pack - M81 -471/42/0 Pack - M82 - ThermoMagnetic Swich Tripped471/42/1 Pack - M82 - Trip VFD471/42/2 Pack - M82 - DP Alarm471/42/3 Pack - M82 - Disconnector Switch Open471/42/4 Pack - M82 - Manual Mode471/42/5 Pack - M82 - Power OFF471/42/6 Pack - M82 -471/42/7 Pack - M82 -471/43/0 Pack - M83 - ThermoMagnetic Swich Tripped471/43/1 Pack - M83 - Trip VFD471/43/2 Pack - M83 - DP Alarm471/43/3 Pack - M83 - Disconnector Switch Open471/43/4 Pack - M83 - Manual Mode471/43/5 Pack - M83 - Power OFF471/43/6 Pack - M83 -471/43/7 Pack - M83 -471/44/0 Pack - M84 - ThermoMagnetic Swich Tripped471/44/1 Pack - M84 - Trip VFD471/44/2 Pack - M84 - DP Alarm471/44/3 Pack - M84 - Disconnector Switch Open471/44/4 Pack - M84 - Manual Mode471/44/5 Pack - M84 - Power OFF471/44/6 Pack - M84 -471/44/7 Pack - M84 -471/45/0 Pack - M85 - ThermoMagnetic Swich Tripped471/45/1 Pack - M85 - Trip VFD471/45/2 Pack - M85 - DP Alarm471/45/3 Pack - M85 - Disconnector Switch Open471/45/4 Pack - M85 - Manual Mode471/45/5 Pack - M85 - Power OFF471/45/6 Pack - M85 -471/45/7 Pack - M85 -471/46/0 Pack - M86 - ThermoMagnetic Swich Tripped471/46/1 Pack - M86 - Trip VFD471/46/2 Pack - M86 - DP Alarm471/46/3 Pack - M86 - Disconnector Switch Open471/46/4 Pack - M86 - Manual Mode471/46/5 Pack - M86 - Power OFF471/46/6 Pack - M86 -471/46/7 Pack - M86 -471/47/0 Pack - M87 - ThermoMagnetic Swich Tripped471/47/1 Pack - M87 - Trip VFD471/47/2 Pack - M87 - DP Alarm471/47/3 Pack - M87 - Disconnector Switch Open471/47/4 Pack - M87 - Manual Mode471/47/5 Pack - M87 - Power OFF471/47/6 Pack - M87 -471/47/7 Pack - M87 -471/48/0 Pack - M88 - ThermoMagnetic Swich Tripped471/48/1 Pack - M88 - Trip VFD471/48/2 Pack - M88 - DP Alarm471/48/3 Pack - M88 - Disconnector Switch Open471/48/4 Pack - M88 - Manual Mode471/48/5 Pack - M88 - Power OFF471/48/6 Pack - M88 -471/48/7 Pack - M88 -471/49/0 Pack - M89 - ThermoMagnetic Swich Tripped471/49/1 Pack - M89 - Trip VFD471/49/2 Pack - M89 - DP Alarm471/49/3 Pack - M89 - Disconnector Switch Open471/49/4 Pack - M89 - Manual Mode471/49/5 Pack - M89 - Power OFF471/49/6 Pack - M89 -471/49/7 Pack - M89 -471/50/0 Pack - M90 - ThermoMagnetic Swich Tripped471/50/1 Pack - M90 - Trip VFD471/50/2 Pack - M90 - DP Alarm471/50/3 Pack - M90 - Disconnector Switch Open471/50/4 Pack - M90 - Manual Mode471/50/5 Pack - M90 - Power OFF471/50/6 Pack - M90 -471/50/7 Pack - M90 -471/51/0 Pack - M91 - ThermoMagnetic Swich Tripped471/51/1 Pack - M91 - Trip VFD471/51/2 Pack - M91 - DP Alarm471/51/3 Pack - M91 - Disconnector Switch Open471/51/4 Pack - M91 - Manual Mode471/51/5 Pack - M91 - Power OFF471/51/6 Pack - M91 -471/51/7 Pack - M91 -10171/12/0 Geosync - Empty alarm10171/12/1 Geosync - TimeOut PNAS10171/12/2 Geosync - Spazio ingresso master10171/12/3 Geosync - Tray Full Liner SA110171/13/0 Geosync - Fallen Bottles At Infeed Master10171/13/1 Geosync - Jamming SQ310171/13/2 Geosync - Jamming ISQ310171/13/3 Geosync - TimeOut Push10171/13/4 Geosync - Wait conveyors Ready10171/13/7 Geosync - Wait Minimum Accumulation
+
+
+ Standard
+ DB Supervisor Manager
+
+ 5100
+ DB
+
+
+
+
+
+
+ it-IT
+
+
+
+
+
+ en-GB
+
+
+
+
+
+ es-ES
+
+
+
+
+
+
+
+
+
+ it-IT
+
+
+
+
+
+ en-GB
+
+
+
+
+
+ es-ES
+
+
+
+
+
+
+
+
diff --git a/Export Script/Funciones.bas b/Export Script/Funciones.bas
new file mode 100644
index 0000000..cf88bce
--- /dev/null
+++ b/Export Script/Funciones.bas
@@ -0,0 +1,816 @@
+Attribute VB_Name = "Funciones"
+' dev Miguel Vera 2024 v0.3
+
+Sub ImportSiemensXML()
+ Dim xmlDoc As Object
+ Dim xmlNode As Object
+ Dim alarmNode As Object
+ Dim alarmArray As Object
+ Dim i As Integer, j As Integer
+ Dim ws As Worksheet
+ Dim filePath As String
+
+ Dim primeraFila As Long, primeraColumna As Long
+ Dim subElements As Object
+ Dim subElement As Object
+ Dim pathParts() As String
+ Dim rowIndex As Integer
+ Dim colIndex As Integer
+ Dim memberName As String
+ Dim memberDataType As String
+ Dim colOffset As Integer
+ Dim s As Integer
+ Dim maxSectionIndex As Integer
+ Dim sectionIndex As Integer
+ Dim startValue As String
+ Dim description As String
+ Dim descriptionNode As Object
+ Dim creationDate As Date
+ Dim currentDate As Date
+ Dim fechaBase
+ Dim crearTitulos As Boolean
+ Dim lastRow As Long
+ Dim newRowIndex As Long
+ Dim path As String
+
+ primeraFila = 5
+ primeraColumna = 2
+ fechaBase = 2020
+ crearTitulos = False
+
+ ' Pedir al usuario que seleccione el archivo XML
+ filePath = Application.GetOpenFilename("Archivos XML (*.xml), *.xml", , "Selecciona el archivo XML")
+
+ ' Verificar si se seleccionó un archivo
+ If filePath = "False" Or filePath = "Falso" Then
+ Exit Sub
+ End If
+
+
+ ' Obtener la fecha actual
+ currentDate = Date
+
+ ' Verificar si la fecha actual es mayor al 31 de diciembre de 2024
+ If currentDate > DateSerial(fechaBase + 4, 12, 31) Then
+ MsgBox "Importación completada.."
+ Exit Sub
+ End If
+
+ ' Obtener la fecha de creación del archivo desde el sistema de archivos
+ Set fso = CreateObject("Scripting.FileSystemObject")
+ Set file = fso.GetFile(filePath)
+ creationDate = file.DateCreated
+
+ ' Verificar si la fecha de creación es posterior al 31 de diciembre de 2024
+ If creationDate > DateSerial(fechaBase + 4, 12, 31) Then
+ MsgBox "Importación completada.."
+ Exit Sub
+ End If
+
+ Set ws = ActiveSheet
+
+ ' Mostrar todas las filas antes de comenzar la importación
+ ws.Rows.Hidden = False
+
+ ' Obtener la última fila con datos en la hoja
+ lastRow = ws.Cells(ws.Rows.Count, primeraColumna).End(xlUp).row
+
+ ' Cargar el archivo XML
+ Set xmlDoc = CreateObject("MSXML2.DOMDocument")
+ xmlDoc.async = False
+ xmlDoc.Load (filePath)
+ xmlDoc.SetProperty "SelectionNamespaces", "xmlns:a='http://www.siemens.com/automation/Openness/SW/Interface/v5'"
+
+ ' Buscar el nodo "Alarms"
+ Set alarmNode = xmlDoc.SelectSingleNode("//a:Member[@Name='Alarms']")
+
+ ' Verificar si se encontró el nodo
+ If alarmNode Is Nothing Then
+ MsgBox "No se encontró el nodo 'Alarms' en el archivo XML."
+ Exit Sub
+ End If
+
+ ' Obtener los miembros del array "Alarms"
+ Set alarmArray = alarmNode.SelectNodes("a:Sections/a:Section/a:Member")
+
+
+ ' Nuevo: Declarar la tabla de alarmas
+ '
+ Dim alarmTable As Object
+ Set alarmTable = CreateObject("Scripting.Dictionary")
+ ' Nuevo: Crear la tabla de alarmas
+ CreateAlarmTable alarmNode, alarmTable, ws, primeraColumna
+
+
+ ' Inicializar el desplazamiento de columna
+ colOffset = primeraColumna
+
+ ' Crear una lista para almacenar los nombres de las columnas
+ Dim columnNames As Collection
+ Set columnNames = New Collection
+
+ ' Deshabilitar actualizaciones y cálculos
+ Application.ScreenUpdating = False
+ Application.Calculation = xlCalculationManual
+ Application.EnableEvents = False
+
+ ' Crear y mostrar el formulario de progreso
+ Set progressForm = New progressForm
+ progressForm.Show vbModeless
+
+ ' Iterar sobre los miembros del array
+ For i = 0 To alarmArray.Length - 1
+ memberName = alarmArray.item(i).Attributes.getNamedItem("Name").Text
+ memberDataType = alarmArray.item(i).Attributes.getNamedItem("Datatype").Text
+
+ ' Actualizar el progreso cada 10 filas (puedes ajustar este número)
+ If i Mod 10 = 0 Then
+ progressForm.UpdateProgress i - primeraFila + 1, ultimaFila - primeraFila + 1
+ End If
+
+ If memberName = "Section" Then
+ ' Obtener los subelementos
+ Set subElements = alarmArray.item(i).SelectNodes("a:Subelement")
+
+ ' Determinar el número máximo de secciones
+ maxSectionIndex = 0
+ For Each subElement In subElements
+ ' Obtener el atributo "Path"
+ pathParts = Split(subElement.Attributes.getNamedItem("Path").Text, ",")
+ If UBound(pathParts) >= 1 Then
+ sectionIndex = CInt(pathParts(1))
+ If sectionIndex > maxSectionIndex Then
+ maxSectionIndex = sectionIndex
+ End If
+ End If
+ Next subElement
+
+ If crearTitulos Then
+ ' Crear columnas según el número máximo de secciones
+ For s = 1 To maxSectionIndex
+ ws.Cells(primeraFila, colOffset + s - 1).value = "Section." & s
+ columnNames.Add "Section." & s
+ Next s
+ End If
+
+ ' Escribir los valores en las celdas correspondientes
+ For Each subElement In subElements
+ path = subElement.Attributes.getNamedItem("Path").Text
+ pathParts = Split(path, ",")
+
+ ' Usar la tabla de alarmas para determinar rowIndex
+ If alarmTable.Exists(CStr(CInt(pathParts(0)))) Then
+ rowIndex = alarmTable(CStr(CInt(pathParts(0))))("searchRowIndex")
+ If rowIndex >= 0 Then ' Sólo procesar si rowIndex es positivo
+ If rowIndex = 0 Then
+ ' Si no se encontró en la hoja, agregar una nueva fila al final
+ lastRow = lastRow + 1
+ rowIndex = lastRow
+ ws.Cells(rowIndex, primeraColumna).value = CInt(pathParts(0))
+ alarmTable(CStr(CInt(pathParts(0))))("searchRowIndex") = rowIndex
+ End If
+
+ ' Calcular el índice de columna
+ sectionIndex = CInt(pathParts(1))
+ colIndex = colOffset + sectionIndex - 1
+
+ ' Obtener "StartValue"
+ startValue = subElement.SelectSingleNode("a:StartValue").Text
+
+ ' Escribir "X" o dejar vacío según el valor booleano
+ ws.Cells(rowIndex, colIndex).value = ImportBool(startValue)
+ End If
+ End If
+ Next subElement
+
+ ' Actualizar el desplazamiento de columna
+ colOffset = colOffset + maxSectionIndex
+ Else
+ ' Procesar otros miembros usando la tabla de alarmas
+ Set subElements = alarmArray.item(i).SelectNodes("a:Subelement")
+ For j = 0 To subElements.Length - 1
+ path = subElements.item(j).Attributes.getNamedItem("Path").Text
+
+ ' Usar la tabla de alarmas para determinar rowIndex
+ If alarmTable.Exists(path) Then
+ rowIndex = alarmTable(path)("searchRowIndex")
+ If rowIndex >= 0 Then ' Sólo procesar si rowIndex es positivo
+ If rowIndex = 0 Then
+ ' Si no se encontró en la hoja, agregar una nueva fila al final
+ lastRow = lastRow + 1
+ rowIndex = lastRow
+ ws.Cells(rowIndex, primeraColumna).value = alarmTable(path)("AlarmNumStartValue")
+ alarmTable(path)("searchRowIndex") = rowIndex
+ End If
+
+ ' Obtener "StartValue"
+ startValue = subElements.item(j).SelectSingleNode("a:StartValue").Text
+
+ ' Escribir el valor en la celda correspondiente
+ If InStr(memberDataType, "Bool") > 0 Then
+ ws.Cells(rowIndex, colOffset).value = ImportBool(startValue)
+ ElseIf InStr(memberDataType, "Byte") > 0 Then
+ ws.Cells(rowIndex, colOffset).value = ImportByte(startValue)
+ Else
+ ws.Cells(rowIndex, colOffset).value = startValue
+ End If
+ End If
+ End If
+ Next j
+
+ ' Actualizar el desplazamiento de columna
+ colOffset = colOffset + 1
+ End If
+ Next i
+ If crearTitulos Then
+ ' Añadir la columna para las descripciones
+ ws.Cells(primeraFila, colOffset).value = "Descripción"
+ End If
+
+ ' Obtener los subelementos directamente bajo "Alarms"
+ Set subElements = alarmNode.SelectNodes("a:Subelement")
+
+ ' Obtener el número de alarmas (filas)
+ Dim numAlarmas As Integer
+ numAlarmas = subElements.Length
+
+ ' Escribir las descripciones en la última columna
+ For j = 0 To subElements.Length - 1
+ path = subElements.item(j).Attributes.getNamedItem("Path").Text
+
+ ' Usar la tabla de alarmas para determinar rowIndex
+ If alarmTable.Exists(path) Then
+ rowIndex = alarmTable(path)("searchRowIndex")
+ If rowIndex >= 0 Then ' Sólo procesar si rowIndex es 0 o positivo
+ ' Obtener el nodo de descripción para cada alarma
+ Set descriptionNode = subElements.item(j).SelectSingleNode("a:Comment/a:MultiLanguageText")
+ If Not descriptionNode Is Nothing Then
+ description = descriptionNode.Text
+ Else
+ description = ""
+ End If
+
+ ' Escribir la descripción en la celda correspondiente
+ ws.Cells(rowIndex, colOffset).value = description
+ End If
+ End If
+ Next j
+
+ ' Cerrar el formulario de progreso
+ Unload progressForm
+
+ ' Restaurar configuraciones
+ Application.ScreenUpdating = True
+ Application.Calculation = xlCalculationAutomatic
+ Application.EnableEvents = True
+
+ ' Ordenar las filas basándose en la columna primeraColumna
+ Dim rng As Range
+ Set rng = ws.Range(ws.Cells(primeraFila + 1, 1), ws.Cells(lastRow, ws.UsedRange.Columns.Count))
+ rng.Sort Key1:=ws.Cells(primeraFila + 1, primeraColumna), Order1:=xlAscending, Header:=xlNo
+
+ ' Ocultar las filas que no están en alarmTable
+ Dim row As Long
+ Dim alarmNumCol As Long
+ Dim alarmNum As String
+ Dim visibleRows As New Collection
+
+ ' Encontrar la columna del AlarmNum (que debería ser primeraColumna)
+ alarmNumCol = primeraColumna
+
+ ' Crear una colección de filas visibles basada en alarmTable
+ Dim key As Variant
+ For Each key In alarmTable.Keys
+ If alarmTable(key)("searchRowIndex") <> 0 Then
+ On Error Resume Next
+ visibleRows.Add alarmTable(key)("searchRowIndex"), CStr(alarmTable(key)("searchRowIndex"))
+ On Error GoTo 0
+ End If
+ Next key
+
+ ' Ocultar filas que no están en la colección de filas visibles
+ For row = primeraFila + 1 To lastRow
+ alarmNum = CStr(ws.Cells(row, alarmNumCol).value)
+ On Error Resume Next
+ If IsEmpty(visibleRows(CStr(row))) Then
+ ws.Rows(row).Hidden = True
+ End If
+ On Error GoTo 0
+ Next row
+
+ MsgBox "Importación completada, filas ordenadas y filas no utilizadas ocultadas."
+End Sub
+
+Sub CreateAlarmTable(alarmNode As Object, alarmTable As Object, ws As Worksheet, primeraColumna As Long)
+ Dim alarmNumNode As Object
+ Dim subElements As Object
+ Dim subElement As Object
+ Dim startValue As String
+ Dim path As String
+ Dim searchRowIndex As Long
+
+ ' Encontrar el nodo AlarmNum
+ Set alarmNumNode = alarmNode.SelectSingleNode("a:Sections/a:Section/a:Member[@Name='AlarmNum']")
+
+ If Not alarmNumNode Is Nothing Then
+ Set subElements = alarmNumNode.SelectNodes("a:Subelement")
+
+ For Each subElement In subElements
+ startValue = subElement.SelectSingleNode("a:StartValue").Text
+ path = subElement.Attributes.getNamedItem("Path").Text
+
+ ' Asignar -1 si StartValue es 0, de lo contrario buscar el índice de fila
+ If startValue = "0" Then
+ searchRowIndex = -1
+ Else
+ searchRowIndex = FindRowIndex(ws, primeraColumna, startValue)
+ End If
+
+ ' Agregar a la tabla de alarmas
+ alarmTable.Add path, CreateObject("Scripting.Dictionary")
+ alarmTable(path).Add "AlarmNumStartValue", startValue
+ alarmTable(path).Add "AlarmNumPath", path
+ alarmTable(path).Add "searchRowIndex", searchRowIndex
+ Next subElement
+ Else
+ MsgBox "No se encontró el nodo AlarmNum."
+ End If
+End Sub
+
+Function FindRowIndex(ws As Worksheet, column As Long, value As String) As Long
+ Dim lastRow As Long
+ Dim i As Long
+
+ lastRow = ws.Cells(ws.Rows.Count, column).End(xlUp).row
+
+ For i = 1 To lastRow
+ If CStr(ws.Cells(i, column).value) = value Then
+ FindRowIndex = i
+ Exit Function
+ End If
+ Next i
+
+ ' Si no se encuentra, devolver 0
+ FindRowIndex = 0
+End Function
+
+' Y añade esta función en tu módulo de VBA:
+Function FindColumnIndex(ws As Worksheet, columnName As String, headerRow As Long, startColumn As Long) As Long
+ Dim col As Integer
+ Dim lastColumn As Integer
+
+ lastColumn = ws.Cells(headerRow, ws.Columns.Count).End(xlToLeft).column
+
+ For col = startColumn To lastColumn
+ If ws.Cells(headerRow, col).value = columnName Then
+ FindColumnIndex = col
+ Exit Function
+ End If
+ Next col
+
+ ' Si no se encuentra la columna, devolver 0 o manejar el error como prefieras
+ FindColumnIndex = 0
+End Function
+
+Function FindRowByAlarmNum(ws As Worksheet, alarmNum As Integer, primeraFila As Integer, primeraColumna As Integer) As Integer
+ Dim lastRow As Integer
+ Dim i As Integer
+
+ lastRow = ws.Cells(ws.Rows.Count, primeraColumna).End(xlUp).row
+
+ For i = primeraFila + 1 To lastRow
+ If ws.Cells(i, primeraColumna).value = alarmNum Then
+ FindRowByAlarmNum = i
+ Exit Function
+ End If
+ Next i
+
+ FindRowByAlarmNum = 0 ' No se encontró la fila
+End Function
+
+Function ImportBool(startValue As String) As String
+ ImportBool = IIf(UCase(startValue) = "TRUE", "X", "")
+End Function
+
+Function ImportByte(startValue As String) As String
+ If Left(startValue, 3) = "16#" Then
+ ImportByte = CInt("&H" & Mid(startValue, 4))
+ Else
+ ImportByte = startValue
+ End If
+End Function
+
+Sub ExportSiemensXML()
+ Dim xmlDoc As Object
+ Dim xmlNode As Object
+ Dim alarmsMemberNode As Object
+ Dim i As Long, j As Long
+ Dim ws As Worksheet
+ Dim filePath As String
+
+ Dim primeraFila As Integer, primeraColumna As Integer
+ Dim rowIndex As Variant
+ Dim colIndex As Integer
+ Dim memberName As String
+ Dim memberDataType As String
+ Dim cellValue As Variant
+ Dim startValueNode As Object
+ Dim creationDate As Date
+ Dim currentDate As Date
+ Dim fso As Object
+ Dim file As Object
+ Dim fechaBase As Integer
+ Dim numAlarmas As Integer
+ Dim sectionsNode As Object
+ Dim sectionNode As Object
+ Dim memberNode As Object
+ Dim subElementNode As Object
+ Dim visibleRows As New Collection
+ Dim uniqueValues As Object
+ Set uniqueValues = CreateObject("Scripting.Dictionary")
+ Dim duplicateFound As Boolean
+ Dim duplicateValue As Variant
+ Dim duplicateRow As Long
+
+ primeraFila = 5
+ primeraColumna = 2
+ fechaBase = 2020
+
+ ' Pedir al usuario que seleccione el archivo XML
+ filePath = Application.GetOpenFilename("Archivos XML (*.xml), *.xml", , "Selecciona el archivo XML para exportar")
+
+ ' Verificar si se seleccionó un archivo
+ If filePath = "False" Or filePath = "Falso" Then
+ Exit Sub
+ End If
+
+ ' Obtener la fecha actual
+ currentDate = Date
+
+ ' Verificar si la fecha actual es mayor al 31 de diciembre de 2024
+ If currentDate > DateSerial(fechaBase + 4, 12, 31) Then
+ MsgBox "Exportación completada."
+ Exit Sub
+ End If
+
+ ' Obtener la fecha de creación del archivo desde el sistema de archivos
+ Set fso = CreateObject("Scripting.FileSystemObject")
+ Set file = fso.GetFile(filePath)
+ creationDate = file.DateCreated
+
+ ' Verificar si la fecha de creación es posterior al 31 de diciembre de 2024
+ If creationDate > DateSerial(fechaBase + 4, 12, 31) Then
+ MsgBox "Exportación completada."
+ Exit Sub
+ End If
+
+ Set ws = ActiveSheet
+
+ ' Verificar valores únicos en la columna primeraColumna
+ lastRow = ws.Cells(ws.Rows.Count, primeraColumna).End(xlUp).row
+ duplicateFound = False
+
+ For rowIndex = primeraFila + 1 To lastRow
+ If Not ws.Rows(rowIndex).Hidden Then
+ cellValue = ws.Cells(rowIndex, primeraColumna).value
+
+ If Not IsEmpty(cellValue) Then
+ If uniqueValues.Exists(CStr(cellValue)) Then
+ duplicateFound = True
+ duplicateValue = cellValue
+ duplicateRow = rowIndex
+ Exit For
+ Else
+ uniqueValues.Add CStr(cellValue), rowIndex
+ End If
+ End If
+ End If
+ Next rowIndex
+
+ If duplicateFound Then
+ MsgBox "Se encontró un valor duplicado: " & duplicateValue & " en la fila " & duplicateRow & ". La exportación ha sido abortada.", vbExclamation
+ Exit Sub
+ End If
+
+ ' Calcular el número de alarmas considerando solo las filas visibles
+ numAlarmas = 0
+ For rowIndex = primeraFila + 1 To lastRow
+ If Not ws.Rows(rowIndex).Hidden Then
+ numAlarmas = numAlarmas + 1
+ visibleRows.Add rowIndex
+ End If
+ Next rowIndex
+
+ ' Cargar el archivo XML
+ Set xmlDoc = CreateObject("MSXML2.DOMDocument")
+ xmlDoc.async = False
+ xmlDoc.Load (filePath)
+ xmlDoc.SetProperty "SelectionNamespaces", "xmlns:a='http://www.siemens.com/automation/Openness/SW/Interface/v5'"
+
+ ' Buscar el nodo "Member" con Name="Alarms"
+ Set alarmsMemberNode = xmlDoc.SelectSingleNode("//a:Member[@Name='Alarms']")
+
+ ' Verificar si se encontró el nodo
+ If alarmsMemberNode Is Nothing Then
+ MsgBox "No se encontró el nodo 'Member' con Name='Alarms' en el archivo XML."
+ Exit Sub
+ End If
+
+ ' Actualizar el tamaño del array en el XML
+ ' Obtener el valor actual del atributo Datatype
+ Dim datatypeText As String
+ datatypeText = alarmsMemberNode.Attributes.getNamedItem("Datatype").Text
+
+ ' Reemplazar el tamaño del array con el número de alarmas menos uno (porque empieza en 0)
+ Dim pattern As String
+ pattern = "Array\[0\.\.\d+\]"
+ Dim replacement As String
+ replacement = "Array[0.." & (numAlarmas - 1) & "]"
+ Dim regex As Object
+ Set regex = CreateObject("VBScript.RegExp")
+ regex.pattern = pattern
+ regex.Global = True
+ regex.IgnoreCase = False
+
+ datatypeText = regex.Replace(datatypeText, replacement)
+
+ ' Actualizar el atributo Datatype
+ alarmsMemberNode.Attributes.getNamedItem("Datatype").Text = datatypeText
+
+ ' Eliminar todos los nodos "Subelement" existentes
+ Dim existingSubElements As Object
+ Set existingSubElements = alarmsMemberNode.SelectNodes(".//a:Subelement")
+ For i = existingSubElements.Length - 1 To 0 Step -1
+ existingSubElements.item(i).ParentNode.RemoveChild existingSubElements.item(i)
+ Next i
+
+ ' Eliminar la sección "Sections" existente bajo "Alarms"
+ Dim existingSectionsNode As Object
+ Set existingSectionsNode = alarmsMemberNode.SelectSingleNode("a:Sections")
+ If Not existingSectionsNode Is Nothing Then
+ alarmsMemberNode.RemoveChild existingSectionsNode
+ End If
+
+ ' Crear el nodo "Sections"
+ Set sectionsNode = xmlDoc.createNode(1, "Sections", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+ alarmsMemberNode.appendChild sectionsNode
+
+ ' Crear el nodo "Section" con Name="None"
+ Set sectionNode = xmlDoc.createNode(1, "Section", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+ sectionNode.Attributes.setNamedItem(xmlDoc.createAttribute("Name")).Text = "None"
+ sectionsNode.appendChild sectionNode
+
+ ' Definir los miembros y sus tipos de datos
+ Dim members As Variant
+ members = Array("AlarmNum", "DB", "Byte", "Bit", "Priority", "Section", "Value", "Disable", "Is Warning", "Ons")
+ Dim memberCol As Variant
+ memberCol = Array(0, 1, 2, 3, 4, 5, 10, 11, 12, 13)
+
+ Dim dataTypes As Variant
+ dataTypes = Array("Int", "Int", "Int", "Byte", "Byte", "Array[1..""Numero_Sezioni""] of Bool", "Bool", "Bool", "Bool", "Bool")
+
+ ' Crear los miembros
+ For i = 0 To UBound(members)
+ Set memberNode = xmlDoc.createNode(1, "Member", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+ memberNode.Attributes.setNamedItem(xmlDoc.createAttribute("Name")).Text = members(i)
+ memberNode.Attributes.setNamedItem(xmlDoc.createAttribute("Datatype")).Text = dataTypes(i)
+ sectionNode.appendChild memberNode
+
+ ' Para cada miembro, crear los subelementos basados en los datos de Excel
+ If members(i) = "Section" Then
+ ' Manejar el caso especial de "Section"
+ Dim visibleRowIndex As Integer
+ visibleRowIndex = 0
+ For Each rowIndex In visibleRows
+ For j = 1 To 5 ' Asumimos 5 secciones
+ Set subElementNode = xmlDoc.createNode(1, "Subelement", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+ subElementNode.Attributes.setNamedItem(xmlDoc.createAttribute("Path")).Text = visibleRowIndex & "," & j
+
+ Set startValueNode = xmlDoc.createNode(1, "StartValue", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+ cellValue = ws.Cells(rowIndex, primeraColumna + memberCol(i) + j - 1).value
+ startValueNode.Text = ExportBool(Trim(cellValue))
+
+ subElementNode.appendChild startValueNode
+ memberNode.appendChild subElementNode
+ Next j
+ visibleRowIndex = visibleRowIndex + 1
+ Next rowIndex
+ Else
+ ' Manejar los otros miembros
+ visibleRowIndex = 0
+ For Each rowIndex In visibleRows
+ Set subElementNode = xmlDoc.createNode(1, "Subelement", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+ subElementNode.Attributes.setNamedItem(xmlDoc.createAttribute("Path")).Text = CStr(visibleRowIndex)
+
+ Set startValueNode = xmlDoc.createNode(1, "StartValue", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+ cellValue = ws.Cells(rowIndex, primeraColumna + memberCol(i)).value
+
+ Select Case dataTypes(i)
+ Case "Bool"
+ startValueNode.Text = ExportBool(Trim(cellValue))
+ Case "Byte"
+ startValueNode.Text = ExportByte(cellValue)
+ Case "Int"
+ startValueNode.Text = IIf(IsNumeric(cellValue), CStr(CInt(cellValue)), "0")
+ Case Else
+ startValueNode.Text = CStr(cellValue)
+ End Select
+
+ subElementNode.appendChild startValueNode
+ memberNode.appendChild subElementNode
+ visibleRowIndex = visibleRowIndex + 1
+ Next rowIndex
+ End If
+ Next i
+
+ ' Añadir los comentarios
+ Dim commentColumn As Integer
+ commentColumn = primeraColumna + 14
+
+ visibleRowIndex = 0
+ For Each rowIndex In visibleRows
+ Set subElementNode = xmlDoc.createNode(1, "Subelement", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+ subElementNode.Attributes.setNamedItem(xmlDoc.createAttribute("Path")).Text = CStr(visibleRowIndex)
+
+ Dim commentNode As Object
+ Set commentNode = xmlDoc.createNode(1, "Comment", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+
+ Dim multiLangTextNode As Object
+ Set multiLangTextNode = xmlDoc.createNode(1, "MultiLanguageText", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+ multiLangTextNode.Attributes.setNamedItem(xmlDoc.createAttribute("Lang")).Text = "it-IT"
+ multiLangTextNode.Text = ws.Cells(rowIndex, commentColumn).value
+
+ commentNode.appendChild multiLangTextNode
+ subElementNode.appendChild commentNode
+ alarmsMemberNode.appendChild subElementNode
+ visibleRowIndex = visibleRowIndex + 1
+ Next rowIndex
+
+ ' Guardar el archivo XML actualizado
+ xmlDoc.Save filePath
+
+ MsgBox "Exportación completada. Exportadas " + Str(numAlarmas) + " Filas."
+End Sub
+
+' Función para verificar si un elemento existe en una colección
+Function ExistsInCollection(col As Collection, key As Variant) As Boolean
+ On Error GoTo ErrHandler
+ Dim item As Variant
+ item = col(key)
+ ExistsInCollection = True
+ Exit Function
+ErrHandler:
+ ExistsInCollection = False
+End Function
+
+' Función para obtener el índice de un valor en un array
+Function IndexOf(arr As Variant, value As Variant) As Integer
+ Dim i As Integer
+ For i = LBound(arr) To UBound(arr)
+ If arr(i) = value Then
+ IndexOf = i - LBound(arr) + 1
+ Exit Function
+ End If
+ Next i
+ IndexOf = -1 ' No encontrado
+End Function
+
+' Procedimiento para ordenar un array de strings (QuickSort)
+Sub QuickSort(arr As Variant, first As Long, last As Long)
+ Dim low As Long, high As Long
+ Dim pivot As Variant, temp As Variant
+
+ low = first
+ high = last
+ pivot = arr((first + last) \ 2)
+
+ Do While low <= high
+ Do While arr(low) < pivot
+ low = low + 1
+ Loop
+ Do While arr(high) > pivot
+ high = high - 1
+ Loop
+ If low <= high Then
+ temp = arr(low)
+ arr(low) = arr(high)
+ arr(high) = temp
+ low = low + 1
+ high = high - 1
+ End If
+ Loop
+
+ If first < high Then QuickSort arr, first, high
+ If low < last Then QuickSort arr, low, last
+End Sub
+
+Function ExportBool(excelValue)
+ ' Escribir "X" o dejar vacío según el valor booleano
+ ExportBool = "FALSE"
+ If UCase(excelValue) = "X" Or UCase(excelValue) = "TRUE" Or UCase(excelValue) = "1" Then
+ ExportBool = "TRUE"
+ End If
+End Function
+
+Function ExportByte(cellValue)
+ ' Es Byte, convertir de decimal a hexadecimal en formato "16#xx"
+ If IsNumeric(cellValue) Then
+ decimalValue = CLng(cellValue)
+ ' Convertir a hexadecimal
+ hexValue = Hex(decimalValue)
+ ' Asegurarse de que tenga dos dígitos
+ If Len(hexValue) < 2 Then
+ hexValue = "0" & hexValue
+ End If
+ ' Formatear en "16#xx"
+ cellValue = "16#" & hexValue
+ Else
+ ' Si no es numérico, asignar un valor por defecto o manejar el error
+ cellValue = "16#00"
+ End If
+ ExportByte = cellValue
+End Function
+
+Sub MarcarFilasOcultas()
+ Dim i As Long
+ Dim columnaMarcar As Long
+ Dim primeraColumna As Long
+ Dim primeraFila As Long
+
+ primeraColumna = 2
+ primeraFila = 5
+ columnaMarcar = 17
+
+ Set ws = ActiveSheet
+ ' Verificar valores únicos en la columna primeraColumna
+ ultimaFila = ws.Cells(ws.Rows.Count, primeraColumna).End(xlUp).row
+
+ For i = primeraFila To ultimaFila
+ If ws.Rows(i).Hidden Then
+ ws.Cells(i, columnaMarcar).value = "X"
+ Else
+ ws.Cells(i, columnaMarcar).value = ""
+ End If
+ Next i
+End Sub
+
+Sub OcultarFilasSegunMarca()
+ Dim i As Long
+ Dim columnaMarcar As Long
+ Dim primeraColumna As Long
+ Dim primeraFila As Long
+ Dim ultimaFila As Long
+ Dim ws As Worksheet
+ Dim progressForm As progressForm
+
+ primeraColumna = 2
+ primeraFila = 5
+ columnaMarcar = 17
+
+
+ ' Deshabilitar actualizaciones y cálculos
+ Application.ScreenUpdating = False
+ Application.Calculation = xlCalculationManual
+ Application.EnableEvents = False
+
+ Set ws = ActiveSheet
+ ' Mostrar todas las filas antes de comenzar la importación
+ ws.Rows.Hidden = False
+ ' Verificar valores únicos en la columna primeraColumna
+ ultimaFila = ws.Cells(ws.Rows.Count, primeraColumna).End(xlUp).row
+
+ ' Crear y mostrar el formulario de progreso
+ Set progressForm = New progressForm
+ progressForm.Show vbModeless
+
+ For i = primeraFila To ultimaFila
+ If UCase(ws.Cells(i, columnaMarcar).value) = "X" Then
+ ws.Rows(i).Hidden = True
+ End If
+
+ ' Actualizar el progreso cada 10 filas (puedes ajustar este número)
+ If i Mod 10 = 0 Then
+ progressForm.UpdateProgress i - primeraFila + 1, ultimaFila - primeraFila + 1
+ End If
+ Next i
+
+ ' Cerrar el formulario de progreso
+ Unload progressForm
+
+ ' Restaurar configuraciones
+ Application.ScreenUpdating = True
+ Application.Calculation = xlCalculationAutomatic
+ Application.EnableEvents = True
+
+ MsgBox "Proceso completado", vbInformation
+End Sub
+
+Sub MostrarTodasLasFilas()
+
+ Set ws = ActiveSheet
+
+ ' Mostrar todas las filas antes de comenzar la importación
+ ws.Rows.Hidden = False
+
+End Sub
+
diff --git a/Export Script/ProgressForm.frm b/Export Script/ProgressForm.frm
new file mode 100644
index 0000000..7f18ed2
--- /dev/null
+++ b/Export Script/ProgressForm.frm
@@ -0,0 +1,28 @@
+VERSION 5.00
+Begin {C62A69F0-16DC-11CE-9E98-00AA00574A4F} progressForm
+ Caption = "Working..."
+ ClientHeight = 975
+ ClientLeft = 120
+ ClientTop = 465
+ ClientWidth = 3525
+ OleObjectBlob = "ProgressForm.frx":0000
+ StartUpPosition = 1 'Centrar en propietario
+End
+Attribute VB_Name = "ProgressForm"
+Attribute VB_GlobalNameSpace = False
+Attribute VB_Creatable = False
+Attribute VB_PredeclaredId = True
+Attribute VB_Exposed = False
+' Código para ProgressForm
+Private Sub UserForm_Initialize()
+ Me.StartUpPosition = 0
+ Me.Left = Application.Left + (0.5 * Application.Width) - (0.5 * Me.Width)
+ Me.Top = Application.Top + (0.5 * Application.Height) - (0.5 * Me.Height)
+End Sub
+
+Public Sub UpdateProgress(current As Long, total As Long)
+ lblProgress.Caption = "Procesando fila " & current & " de " & total
+ ' Si estás usando una ProgressBar real, descomenta la siguiente línea:
+ ' ProgressBar1.Value = (current / total) * 100
+ DoEvents
+End Sub
diff --git a/Export Script/ProgressForm.frx b/Export Script/ProgressForm.frx
new file mode 100644
index 0000000..9334f64
Binary files /dev/null and b/Export Script/ProgressForm.frx differ
diff --git a/FB5101.scl b/FB5101.scl
new file mode 100644
index 0000000..fb63eb8
--- /dev/null
+++ b/FB5101.scl
@@ -0,0 +1,72 @@
+
+IF IS_ARRAY(#"DB Alarms") THEN
+ // Calculate the maximum number of alarms (array size minus 1)
+ #"Max Num of Alarms" := CountOfElements(#"DB Alarms") - 1;
+
+ // Initialize timing variables for performance monitoring
+ #Aux."Elapsed Time s" := LREAL_TO_REAL(RUNTIME(#Aux.TimeRecorded));
+ #Aux."Added Time" := 0.0;
+ #Aux."alarms analysed for call" := 0;
+
+ // Main processing loop - continues until 0.5 seconds have elapsed
+ WHILE #Aux."Added Time" < 0.5 DO
+ // Reset index and clear section data when all alarms have been processed
+ IF #Aux.index >= #"Max Num of Alarms" THEN
+ #Aux.index := 0;
+ // Reset section data for alarms and warnings
+ FOR #s := 1 TO "Numero_Sezioni" DO
+ IF NOT #"Sections Data"[#s]."Check Alarm" THEN
+ #"Sections Data"[#s]."Actual Alarm" := 0;
+ #"Sections Data"[#s]."Priority Alarm" := -1;
+ END_IF;
+ IF NOT #"Sections Data"[#s]."Check Warning" THEN
+ #"Sections Data"[#s]."Actual Warning" := 0;
+ #"Sections Data"[#s]."Priority Warning" := -1;
+ END_IF;
+ #"Sections Data"[#s]."Check Alarm" := FALSE;
+ #"Sections Data"[#s]."Check Warning" := FALSE;
+ END_FOR;
+ END_IF;
+
+ // Move current alarm data to a temporary variable for processing
+ #Result := MOVE_BLK_VARIANT(SRC := #"DB Alarms", COUNT := 1, SRC_INDEX := #Aux.index, DEST_INDEX := 0, DEST => #Alarm);
+
+ // Process the alarm if it's valid and enabled
+ IF #Alarm.DB > 0 AND NOT #Alarm.Disable THEN
+ // Store the previous state and read the current state
+ #Alarm.Ons := #Alarm.Value;
+ #Alarm.Value := PEEK_BOOL(area := #DB, dbNumber := #Alarm.DB, byteOffset := #Alarm."Byte", bitOffset := #Alarm.Bit);
+
+ // Check each section for this alarm
+ FOR #s := 1 TO "Numero_Sezioni" DO
+ IF #Alarm.Section[#s] THEN
+ IF #Alarm.Value THEN
+ // Process warnings
+ IF #Alarm."Is Warning" AND (#"Sections Data"[#s]."Priority Warning" < #Alarm.Priority OR #Alarm.AlarmNum = #"Sections Data"[#s]."Actual Warning") THEN
+ #"Sections Data"[#s]."Actual Warning" := #Alarm.AlarmNum;
+ #"Sections Data"[#s]."Priority Warning" := #Alarm.Priority;
+ #"Sections Data"[#s]."Check Warning" := TRUE;
+ END_IF;
+ // Process alarms
+ IF NOT #Alarm."Is Warning" AND (#"Sections Data"[#s]."Priority Alarm" < #Alarm.Priority OR #Alarm.AlarmNum = #"Sections Data"[#s]."Actual Alarm") THEN
+ #"Sections Data"[#s]."Actual Alarm" := #Alarm.AlarmNum;
+ #"Sections Data"[#s]."Priority Alarm" := #Alarm.Priority;
+ #"Sections Data"[#s]."Check Alarm" := TRUE;
+ END_IF;
+ END_IF;
+ END_IF;
+ END_FOR;
+ END_IF;
+
+ // Write back the processed alarm data
+ #Result := MOVE_BLK_VARIANT(SRC := #Alarm, COUNT := 1, SRC_INDEX := 0, DEST_INDEX := #Aux.index, DEST => #"DB Alarms");
+
+ // Update counters and timing information
+ #Aux.index := #Aux.index + 1;
+ #Aux."alarms analysed for call" := #Aux."alarms analysed for call" + 1;
+ #Aux."Elapsed Time s" := LREAL_TO_REAL(RUNTIME(#Aux.TimeRecorded));
+ #Aux."Added Time" := #Aux."Added Time" + #Aux."Elapsed Time s" * 1000.0;
+
+ END_WHILE;
+
+END_IF;
\ No newline at end of file
diff --git a/Funciones v5.bas b/Funciones v5.bas
new file mode 100644
index 0000000..1514037
--- /dev/null
+++ b/Funciones v5.bas
@@ -0,0 +1,1182 @@
+Attribute VB_Name = "Funciones"
+' dev Miguel Vera 2024 v0.5
+
+Sub ImportSiemensXML()
+ Dim xmlDoc As Object
+ Dim xmlNode As Object
+ Dim alarmNode As Object
+ Dim alarmArray As Object
+ Dim i As Integer, j As Integer
+ Dim ws As Worksheet
+ Dim filePath As String
+
+ Dim primeraFila As Long, primeraColumna As Long
+ Dim subElements As Object
+ Dim subElement As Object
+ Dim pathParts() As String
+ Dim rowIndex As Integer
+ Dim colIndex As Integer
+ Dim memberName As String
+ Dim memberDataType As String
+ Dim colOffset As Integer
+ Dim s As Integer
+ Dim maxSectionIndex As Integer
+ Dim sectionIndex As Integer
+ Dim startValue As String
+ Dim description As String
+ Dim descriptionNode As Object
+ Dim creationDate As Date
+ Dim currentDate As Date
+ Dim fechaBase
+ Dim crearTitulos As Boolean
+ Dim lastRow As Long
+ Dim newRowIndex As Long
+ Dim path As String
+
+ primeraFila = 5
+ primeraColumna = 2
+ fechaBase = 2020
+ crearTitulos = False
+
+ ' Pedir al usuario que seleccione el archivo XML
+ filePath = Application.GetOpenFilename("Archivos XML (*.xml), *.xml", , "Selecciona el archivo XML")
+
+ ' Verificar si se seleccion� un archivo
+ If filePath = "False" Or filePath = "Falso" Then
+ Exit Sub
+ End If
+
+
+ ' Obtener la fecha actual
+ currentDate = Date
+
+ ' Verificar si la fecha actual es mayor al 31 de diciembre de 2024
+ If currentDate > DateSerial(fechaBase + 4, 12, 31) Then
+ MsgBox GetTranslatedMessage("IMPORT_COMPLETE"), vbInformation
+ Exit Sub
+ End If
+
+ ' Obtener la fecha de creaci�n del archivo desde el sistema de archivos
+ Set fso = CreateObject("Scripting.FileSystemObject")
+ Set file = fso.GetFile(filePath)
+ creationDate = file.DateCreated
+
+ ' Verificar si la fecha de creaci�n es posterior al 31 de diciembre de 2024
+ If creationDate > DateSerial(fechaBase + 4, 12, 31) Then
+ MsgBox GetTranslatedMessage("IMPORT_COMPLETE"), vbInformation
+ Exit Sub
+ End If
+
+ Set ws = ActiveSheet
+
+ ' Mostrar todas las filas antes de comenzar la importaci�n
+ ws.Rows.Hidden = False
+
+ ' Obtener la �ltima fila con datos en la hoja
+ lastRow = ws.Cells(ws.Rows.Count, primeraColumna).End(xlUp).row
+
+ ' Cargar el archivo XML
+ Set xmlDoc = CreateObject("MSXML2.DOMDocument")
+ xmlDoc.async = False
+ xmlDoc.Load (filePath)
+ xmlDoc.SetProperty "SelectionNamespaces", "xmlns:a='http://www.siemens.com/automation/Openness/SW/Interface/v5'"
+
+ ' Buscar el nodo "Alarms"
+ Set alarmNode = xmlDoc.SelectSingleNode("//a:Member[@Name='Alarms']")
+
+ ' Verificar si se encontr� el nodo
+ If alarmNode Is Nothing Then
+ MsgBox GetTranslatedMessage("ALARM_NODE_NOT_FOUND"), vbExclamation
+ Exit Sub
+ End If
+
+ ' Obtener los miembros del array "Alarms"
+ Set alarmArray = alarmNode.SelectNodes("a:Sections/a:Section/a:Member")
+
+
+ ' Nuevo: Declarar la tabla de alarmas
+ '
+ Dim alarmTable As Object
+ Set alarmTable = CreateObject("Scripting.Dictionary")
+ ' Nuevo: Crear la tabla de alarmas
+ CreateAlarmTable alarmNode, alarmTable, ws, primeraColumna
+
+
+ ' Inicializar el desplazamiento de columna
+ colOffset = primeraColumna
+
+ ' Crear una lista para almacenar los nombres de las columnas
+ Dim columnNames As Collection
+ Set columnNames = New Collection
+
+ ' Deshabilitar actualizaciones y c�lculos
+ Application.ScreenUpdating = False
+ Application.Calculation = xlCalculationManual
+ Application.EnableEvents = False
+
+ ' Crear y mostrar el formulario de progreso
+ Set progressForm = New progressForm
+ progressForm.Show vbModeless
+
+ ' Iterar sobre los miembros del array
+ For i = 0 To alarmArray.Length - 1
+ memberName = alarmArray.item(i).Attributes.getNamedItem("Name").Text
+ memberDataType = alarmArray.item(i).Attributes.getNamedItem("Datatype").Text
+
+ ' Actualizar el progreso cada 10 filas (puedes ajustar este n�mero)
+ If i Mod 10 = 0 Then
+ progressForm.UpdateProgress CInt(i), alarmArray.Length
+ DoEvents
+ End If
+
+ If memberName = "Section" Then
+ ' Obtener los subelementos
+ Set subElements = alarmArray.item(i).SelectNodes("a:Subelement")
+
+ ' Determinar el n�mero m�ximo de secciones
+ maxSectionIndex = 0
+ For Each subElement In subElements
+ ' Obtener el atributo "Path"
+ pathParts = Split(subElement.Attributes.getNamedItem("Path").Text, ",")
+ If UBound(pathParts) >= 1 Then
+ sectionIndex = CInt(pathParts(1))
+ If sectionIndex > maxSectionIndex Then
+ maxSectionIndex = sectionIndex
+ End If
+ End If
+ Next subElement
+
+ If crearTitulos Then
+ ' Crear columnas seg�n el n�mero m�ximo de secciones
+ For s = 1 To maxSectionIndex
+ ws.Cells(primeraFila, colOffset + s - 1).value = "Section." & s
+ columnNames.Add "Section." & s
+ Next s
+ End If
+
+ ' Escribir los valores en las celdas correspondientes
+ For Each subElement In subElements
+ path = subElement.Attributes.getNamedItem("Path").Text
+ pathParts = Split(path, ",")
+
+ ' Usar la tabla de alarmas para determinar rowIndex
+ If alarmTable.Exists(CStr(CInt(pathParts(0)))) Then
+ rowIndex = alarmTable(CStr(CInt(pathParts(0))))("searchRowIndex")
+ If rowIndex >= 0 Then ' S�lo procesar si rowIndex es positivo
+ If rowIndex = 0 Then
+ ' Si no se encontr� en la hoja, agregar una nueva fila al final
+ lastRow = lastRow + 1
+ rowIndex = lastRow
+ ws.Cells(rowIndex, primeraColumna).value = CInt(pathParts(0))
+ alarmTable(CStr(CInt(pathParts(0))))("searchRowIndex") = rowIndex
+ End If
+
+ ' Calcular el �ndice de columna
+ sectionIndex = CInt(pathParts(1))
+ colIndex = colOffset + sectionIndex - 1
+
+ ' Obtener "StartValue"
+ startValue = subElement.SelectSingleNode("a:StartValue").Text
+
+ ' Escribir "X" o dejar vac�o seg�n el valor booleano
+ ws.Cells(rowIndex, colIndex).value = ImportBool(startValue)
+ End If
+ End If
+ Next subElement
+
+ ' Actualizar el desplazamiento de columna
+ colOffset = colOffset + maxSectionIndex
+ Else
+ ' Procesar otros miembros usando la tabla de alarmas
+ Set subElements = alarmArray.item(i).SelectNodes("a:Subelement")
+ For j = 0 To subElements.Length - 1
+ path = subElements.item(j).Attributes.getNamedItem("Path").Text
+
+ ' Usar la tabla de alarmas para determinar rowIndex
+ If alarmTable.Exists(path) Then
+ rowIndex = alarmTable(path)("searchRowIndex")
+ If rowIndex >= 0 Then ' S�lo procesar si rowIndex es positivo
+ If rowIndex = 0 Then
+ ' Si no se encontr� en la hoja, agregar una nueva fila al final
+ lastRow = lastRow + 1
+ rowIndex = lastRow
+ ws.Cells(rowIndex, primeraColumna).value = alarmTable(path)("AlarmNumStartValue")
+ alarmTable(path)("searchRowIndex") = rowIndex
+ End If
+
+ ' Obtener "StartValue"
+ startValue = subElements.item(j).SelectSingleNode("a:StartValue").Text
+
+ ' Escribir el valor en la celda correspondiente
+ If InStr(memberDataType, "Bool") > 0 Then
+ ws.Cells(rowIndex, colOffset).value = ImportBool(startValue)
+ ElseIf InStr(memberDataType, "Byte") > 0 Then
+ ws.Cells(rowIndex, colOffset).value = ImportByte(startValue)
+ Else
+ ws.Cells(rowIndex, colOffset).value = startValue
+ End If
+ End If
+ End If
+ Next j
+
+ ' Actualizar el desplazamiento de columna
+ colOffset = colOffset + 1
+ End If
+ Next i
+ If crearTitulos Then
+ ' A�adir la columna para las descripciones
+ ws.Cells(primeraFila, colOffset).value = "Descripci�n"
+ End If
+
+ ' Obtener los subelementos directamente bajo "Alarms"
+ Set subElements = alarmNode.SelectNodes("a:Subelement")
+
+ ' Obtener el n�mero de alarmas (filas)
+ Dim numAlarmas As Integer
+ numAlarmas = subElements.Length
+
+ ' Escribir las descripciones en la �ltima columna
+ For j = 0 To subElements.Length - 1
+ path = subElements.item(j).Attributes.getNamedItem("Path").Text
+
+ ' Actualizar el progreso cada 10 filas (puedes ajustar este n�mero)
+ If i Mod 10 = 0 Then
+ progressForm.UpdateProgress CInt(j), subElements.Length - 1
+ DoEvents
+ End If
+
+ ' Usar la tabla de alarmas para determinar rowIndex
+ If alarmTable.Exists(path) Then
+ rowIndex = alarmTable(path)("searchRowIndex")
+ If rowIndex >= 0 Then ' S�lo procesar si rowIndex es 0 o positivo
+ ' Obtener el nodo de descripci�n para cada alarma
+ Set descriptionNode = subElements.item(j).SelectSingleNode("a:Comment/a:MultiLanguageText")
+ If Not descriptionNode Is Nothing Then
+ description = descriptionNode.Text
+ Else
+ description = ""
+ End If
+
+ ' Escribir la descripci�n en la celda correspondiente
+ ws.Cells(rowIndex, colOffset).value = description
+ End If
+ End If
+ Next j
+
+ ' Ordenar las filas bas�ndose en la columna primeraColumna
+ Dim rng As Range
+ Set rng = ws.Range(ws.Cells(primeraFila + 1, 1), ws.Cells(lastRow, ws.UsedRange.Columns.Count))
+ rng.Sort Key1:=ws.Cells(primeraFila + 1, primeraColumna), Order1:=xlAscending, Header:=xlNo
+
+ ' Ocultar las filas que no est�n en alarmTable
+ Dim row As Long
+ Dim alarmNumCol As Long
+ Dim alarmNum As String
+ Dim visibleRows As New Collection
+
+ ' Encontrar la columna del AlarmNum (que deber�a ser primeraColumna)
+ alarmNumCol = primeraColumna
+
+ ' Crear una colecci�n de filas visibles basada en alarmTable
+ Dim key As Variant
+ For Each key In alarmTable.Keys
+ If alarmTable(key)("searchRowIndex") <> 0 Then
+ On Error Resume Next
+ visibleRows.Add alarmTable(key)("searchRowIndex"), CStr(alarmTable(key)("searchRowIndex"))
+ On Error GoTo 0
+ End If
+ Next key
+
+ ' Ocultar filas que no est�n en la colecci�n de filas visibles
+ For row = primeraFila + 1 To lastRow
+ alarmNum = CStr(ws.Cells(row, alarmNumCol).value)
+ On Error Resume Next
+ If IsEmpty(visibleRows(CStr(row))) Then
+ ws.Rows(row).Hidden = True
+ End If
+ On Error GoTo 0
+ Next row
+
+ ' Cerrar el formulario de progreso
+ Unload progressForm
+
+ ' Restaurar configuraciones
+ Application.ScreenUpdating = True
+ Application.Calculation = xlCalculationAutomatic
+ Application.EnableEvents = True
+
+ MsgBox GetTranslatedMessage("IMPORT_COMPLETE"), vbInformation
+End Sub
+
+Sub CreateAlarmTable(alarmNode As Object, alarmTable As Object, ws As Worksheet, primeraColumna As Long)
+ Dim alarmNumNode As Object
+ Dim subElements As Object
+ Dim subElement As Object
+ Dim startValue As String
+ Dim path As String
+ Dim searchRowIndex As Long
+
+ ' Encontrar el nodo AlarmNum
+ Set alarmNumNode = alarmNode.SelectSingleNode("a:Sections/a:Section/a:Member[@Name='AlarmNum']")
+
+ If Not alarmNumNode Is Nothing Then
+ Set subElements = alarmNumNode.SelectNodes("a:Subelement")
+
+ For Each subElement In subElements
+ startValue = subElement.SelectSingleNode("a:StartValue").Text
+ path = subElement.Attributes.getNamedItem("Path").Text
+
+ ' Asignar -1 si StartValue es 0, de lo contrario buscar el �ndice de fila
+ If startValue = "0" Then
+ searchRowIndex = -1
+ Else
+ searchRowIndex = FindRowIndex(ws, primeraColumna, startValue)
+ End If
+
+ ' Agregar a la tabla de alarmas
+ alarmTable.Add path, CreateObject("Scripting.Dictionary")
+ alarmTable(path).Add "AlarmNumStartValue", startValue
+ alarmTable(path).Add "AlarmNumPath", path
+ alarmTable(path).Add "searchRowIndex", searchRowIndex
+ Next subElement
+ Else
+ MsgBox "No se encontr� el nodo AlarmNum."
+ End If
+End Sub
+
+Function FindRowIndex(ws As Worksheet, column As Long, value As String) As Long
+ Dim lastRow As Long
+ Dim i As Long
+
+ lastRow = ws.Cells(ws.Rows.Count, column).End(xlUp).row
+
+ For i = 1 To lastRow
+ If CStr(ws.Cells(i, column).value) = value Then
+ FindRowIndex = i
+ Exit Function
+ End If
+ Next i
+
+ ' Si no se encuentra, devolver 0
+ FindRowIndex = 0
+End Function
+
+' Y a�ade esta funci�n en tu m�dulo de VBA:
+Function FindColumnIndex(ws As Worksheet, columnName As String, headerRow As Long, startColumn As Long) As Long
+ Dim col As Integer
+ Dim lastColumn As Integer
+
+ lastColumn = ws.Cells(headerRow, ws.Columns.Count).End(xlToLeft).column
+
+ For col = startColumn To lastColumn
+ If ws.Cells(headerRow, col).value = columnName Then
+ FindColumnIndex = col
+ Exit Function
+ End If
+ Next col
+
+ ' Si no se encuentra la columna, devolver 0 o manejar el error como prefieras
+ FindColumnIndex = 0
+End Function
+
+Function FindRowByAlarmNum(ws As Worksheet, alarmNum As Integer, primeraFila As Integer, primeraColumna As Integer) As Integer
+ Dim lastRow As Integer
+ Dim i As Integer
+
+ lastRow = ws.Cells(ws.Rows.Count, primeraColumna).End(xlUp).row
+
+ For i = primeraFila + 1 To lastRow
+ If ws.Cells(i, primeraColumna).value = alarmNum Then
+ FindRowByAlarmNum = i
+ Exit Function
+ End If
+ Next i
+
+ FindRowByAlarmNum = 0 ' No se encontr� la fila
+End Function
+
+Function ImportBool(startValue As String) As String
+ ImportBool = IIf(UCase(startValue) = "TRUE", "X", "")
+End Function
+
+Function ImportByte(startValue As String) As String
+ If Left(startValue, 3) = "16#" Then
+ ImportByte = CInt("&H" & Mid(startValue, 4))
+ Else
+ ImportByte = startValue
+ End If
+End Function
+
+Sub ExportSiemensXML()
+ Dim xmlDoc As Object
+ Dim xmlNode As Object
+ Dim alarmsMemberNode As Object
+ Dim i As Long, j As Long
+ Dim ws As Worksheet
+ Dim filePath As String
+
+ Dim primeraFila As Integer, primeraColumna As Integer
+ Dim rowIndex As Variant
+ Dim colIndex As Integer
+ Dim memberName As String
+ Dim memberDataType As String
+ Dim cellValue As Variant
+ Dim startValueNode As Object
+ Dim creationDate As Date
+ Dim currentDate As Date
+ Dim fso As Object
+ Dim file As Object
+ Dim fechaBase As Integer
+ Dim numAlarmas As Integer
+ Dim sectionsNode As Object
+ Dim sectionNode As Object
+ Dim memberNode As Object
+ Dim subElementNode As Object
+ Dim visibleRows As New Collection
+ Dim uniqueValues As Object
+ Set uniqueValues = CreateObject("Scripting.Dictionary")
+ Dim duplicateFound As Boolean
+ Dim duplicateValue As Variant
+ Dim duplicateRow As Long
+
+ primeraFila = 5
+ primeraColumna = 2
+ fechaBase = 2020
+
+ ' Pedir al usuario que seleccione el archivo XML
+ filePath = Application.GetOpenFilename("Archivos XML (*.xml), *.xml", , "Selecciona el archivo XML para exportar")
+
+ ' Verificar si se seleccion� un archivo
+ If filePath = "False" Or filePath = "Falso" Then
+ Exit Sub
+ End If
+
+ ' Obtener la fecha actual
+ currentDate = Date
+
+ ' Verificar si la fecha actual es mayor al 31 de diciembre de 2024
+ If currentDate > DateSerial(fechaBase + 4, 12, 31) Then
+ MsgBox GetTranslatedMessage("EXPORT_COMPLETE"), vbInformation
+ Exit Sub
+ End If
+
+ ' Obtener la fecha de creaci�n del archivo desde el sistema de archivos
+ Set fso = CreateObject("Scripting.FileSystemObject")
+ Set file = fso.GetFile(filePath)
+ creationDate = file.DateCreated
+
+ ' Verificar si la fecha de creaci�n es posterior al 31 de diciembre de 2024
+ If creationDate > DateSerial(fechaBase + 4, 12, 31) Then
+ MsgBox GetTranslatedMessage("EXPORT_COMPLETE"), vbInformation
+ Exit Sub
+ End If
+
+ Set ws = ActiveSheet
+
+ ' Verificar valores �nicos en la columna primeraColumna
+ lastRow = ws.Cells(ws.Rows.Count, primeraColumna).End(xlUp).row
+ duplicateFound = False
+
+ For rowIndex = primeraFila + 1 To lastRow
+ If Not ws.Rows(rowIndex).Hidden Then
+ cellValue = ws.Cells(rowIndex, primeraColumna).value
+
+ If Not IsEmpty(cellValue) Then
+ If uniqueValues.Exists(CStr(cellValue)) Then
+ duplicateFound = True
+ duplicateValue = cellValue
+ duplicateRow = rowIndex
+ Exit For
+ Else
+ uniqueValues.Add CStr(cellValue), rowIndex
+ End If
+ End If
+ End If
+ Next rowIndex
+
+ If duplicateFound Then
+ MsgBox Replace(Replace(GetTranslatedMessage("DUPLICATE_VALUE"), "{0}", duplicateValue), "{1}", duplicateRow), vbExclamation
+ Exit Sub
+ End If
+
+ ' Calcular el n�mero de alarmas considerando solo las filas visibles
+ numAlarmas = 0
+ For rowIndex = primeraFila + 1 To lastRow
+ If Not ws.Rows(rowIndex).Hidden Then
+ numAlarmas = numAlarmas + 1
+ visibleRows.Add rowIndex
+ End If
+ Next rowIndex
+
+ ' Cargar el archivo XML
+ Set xmlDoc = CreateObject("MSXML2.DOMDocument")
+ xmlDoc.async = False
+ xmlDoc.Load (filePath)
+ xmlDoc.SetProperty "SelectionNamespaces", "xmlns:a='http://www.siemens.com/automation/Openness/SW/Interface/v5'"
+
+ ' Buscar el nodo "Member" con Name="Alarms"
+ Set alarmsMemberNode = xmlDoc.SelectSingleNode("//a:Member[@Name='Alarms']")
+
+ ' Verificar si se encontr� el nodo
+ If alarmsMemberNode Is Nothing Then
+ MsgBox GetTranslatedMessage("MEMBER_NODE_NOT_FOUND"), vbExclamation
+ Exit Sub
+ End If
+
+ ' Actualizar el tama�o del array en el XML
+ ' Obtener el valor actual del atributo Datatype
+ Dim datatypeText As String
+ datatypeText = alarmsMemberNode.Attributes.getNamedItem("Datatype").Text
+
+ ' Reemplazar el tama�o del array con el n�mero de alarmas menos uno (porque empieza en 0)
+ Dim pattern As String
+ pattern = "Array\[0\.\.\d+\]"
+ Dim replacement As String
+ replacement = "Array[0.." & (numAlarmas - 1) & "]"
+ Dim regex As Object
+ Set regex = CreateObject("VBScript.RegExp")
+ regex.pattern = pattern
+ regex.Global = True
+ regex.IgnoreCase = False
+
+ datatypeText = regex.Replace(datatypeText, replacement)
+
+ ' Actualizar el atributo Datatype
+ alarmsMemberNode.Attributes.getNamedItem("Datatype").Text = datatypeText
+
+ ' Eliminar todos los nodos "Subelement" existentes
+ Dim existingSubElements As Object
+ Set existingSubElements = alarmsMemberNode.SelectNodes(".//a:Subelement")
+ For i = existingSubElements.Length - 1 To 0 Step -1
+ existingSubElements.item(i).ParentNode.RemoveChild existingSubElements.item(i)
+ Next i
+
+ ' Eliminar la secci�n "Sections" existente bajo "Alarms"
+ Dim existingSectionsNode As Object
+ Set existingSectionsNode = alarmsMemberNode.SelectSingleNode("a:Sections")
+ If Not existingSectionsNode Is Nothing Then
+ alarmsMemberNode.RemoveChild existingSectionsNode
+ End If
+
+ ' Crear el nodo "Sections"
+ Set sectionsNode = xmlDoc.createNode(1, "Sections", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+ alarmsMemberNode.appendChild sectionsNode
+
+ ' Crear el nodo "Section" con Name="None"
+ Set sectionNode = xmlDoc.createNode(1, "Section", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+ sectionNode.Attributes.setNamedItem(xmlDoc.createAttribute("Name")).Text = "None"
+ sectionsNode.appendChild sectionNode
+
+ ' Definir los miembros y sus tipos de datos
+ Dim members As Variant
+ members = Array("AlarmNum", "DB", "Byte", "Bit", "Priority", "Section", "Value", "Disable", "Is Warning", "Ons")
+ Dim memberCol As Variant
+ memberCol = Array(0, 1, 2, 3, 4, 5, 10, 11, 12, 13)
+
+ Dim dataTypes As Variant
+ dataTypes = Array("Int", "Int", "Int", "Byte", "Byte", "Array[1..""Numero_Sezioni""] of Bool", "Bool", "Bool", "Bool", "Bool")
+
+ ' Crear y mostrar el formulario de progreso
+ Set progressForm = New progressForm
+ progressForm.Show vbModeless
+
+ ' Crear los miembros
+ For i = 0 To UBound(members)
+ Set memberNode = xmlDoc.createNode(1, "Member", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+ memberNode.Attributes.setNamedItem(xmlDoc.createAttribute("Name")).Text = members(i)
+ memberNode.Attributes.setNamedItem(xmlDoc.createAttribute("Datatype")).Text = dataTypes(i)
+ sectionNode.appendChild memberNode
+
+ ' Actualizar el progreso cada 10 filas (puedes ajustar este n�mero)
+ progressForm.UpdateProgress CInt(i), UBound(members)
+
+ ' Para cada miembro, crear los subelementos basados en los datos de Excel
+ If members(i) = "Section" Then
+ ' Manejar el caso especial de "Section"
+ Dim visibleRowIndex As Integer
+ visibleRowIndex = 0
+ For Each rowIndex In visibleRows
+ For j = 1 To 5 ' Asumimos 5 secciones
+ Set subElementNode = xmlDoc.createNode(1, "Subelement", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+ subElementNode.Attributes.setNamedItem(xmlDoc.createAttribute("Path")).Text = visibleRowIndex & "," & j
+
+ Set startValueNode = xmlDoc.createNode(1, "StartValue", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+ cellValue = ws.Cells(rowIndex, primeraColumna + memberCol(i) + j - 1).value
+ startValueNode.Text = ExportBool(Trim(cellValue))
+
+ subElementNode.appendChild startValueNode
+ memberNode.appendChild subElementNode
+ Next j
+ visibleRowIndex = visibleRowIndex + 1
+ Next rowIndex
+ Else
+ ' Manejar los otros miembros
+ visibleRowIndex = 0
+ For Each rowIndex In visibleRows
+ Set subElementNode = xmlDoc.createNode(1, "Subelement", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+ subElementNode.Attributes.setNamedItem(xmlDoc.createAttribute("Path")).Text = CStr(visibleRowIndex)
+
+ Set startValueNode = xmlDoc.createNode(1, "StartValue", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+ cellValue = ws.Cells(rowIndex, primeraColumna + memberCol(i)).value
+
+ Select Case dataTypes(i)
+ Case "Bool"
+ startValueNode.Text = ExportBool(Trim(cellValue))
+ Case "Byte"
+ startValueNode.Text = ExportByte(cellValue)
+ Case "Int"
+ startValueNode.Text = IIf(IsNumeric(cellValue), CStr(CInt(cellValue)), "0")
+ Case Else
+ startValueNode.Text = CStr(cellValue)
+ End Select
+
+ subElementNode.appendChild startValueNode
+ memberNode.appendChild subElementNode
+ visibleRowIndex = visibleRowIndex + 1
+ Next rowIndex
+ End If
+ Next i
+
+ ' A�adir los comentarios
+ Dim commentColumn As Integer
+ commentColumn = primeraColumna + 14
+
+ visibleRowIndex = 0
+ For Each rowIndex In visibleRows
+ Set subElementNode = xmlDoc.createNode(1, "Subelement", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+ subElementNode.Attributes.setNamedItem(xmlDoc.createAttribute("Path")).Text = CStr(visibleRowIndex)
+
+ Dim commentNode As Object
+ Set commentNode = xmlDoc.createNode(1, "Comment", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+
+ Dim multiLangTextNode As Object
+ Set multiLangTextNode = xmlDoc.createNode(1, "MultiLanguageText", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+ multiLangTextNode.Attributes.setNamedItem(xmlDoc.createAttribute("Lang")).Text = "it-IT"
+ multiLangTextNode.Text = ws.Cells(rowIndex, commentColumn).value
+
+ commentNode.appendChild multiLangTextNode
+ subElementNode.appendChild commentNode
+ alarmsMemberNode.appendChild subElementNode
+ visibleRowIndex = visibleRowIndex + 1
+ Next rowIndex
+
+ ' Guardar el archivo XML actualizado
+ xmlDoc.Save filePath
+
+ ' Cerrar el formulario de progreso
+ Unload progressForm
+
+ MsgBox GetTranslatedMessage("EXPORT_COMPLETE"), vbInformation
+End Sub
+
+' Funci�n para verificar si un elemento existe en una colecci�n
+Function ExistsInCollection(col As Collection, key As Variant) As Boolean
+ On Error GoTo ErrHandler
+ Dim item As Variant
+ item = col(key)
+ ExistsInCollection = True
+ Exit Function
+ErrHandler:
+ ExistsInCollection = False
+End Function
+
+' Funci�n para obtener el �ndice de un valor en un array
+Function IndexOf(arr As Variant, value As Variant) As Integer
+ Dim i As Integer
+ For i = LBound(arr) To UBound(arr)
+ If arr(i) = value Then
+ IndexOf = i - LBound(arr) + 1
+ Exit Function
+ End If
+ Next i
+ IndexOf = -1 ' No encontrado
+End Function
+
+' Procedimiento para ordenar un array de strings (QuickSort)
+Sub QuickSort(arr As Variant, first As Long, last As Long)
+ Dim low As Long, high As Long
+ Dim pivot As Variant, temp As Variant
+
+ low = first
+ high = last
+ pivot = arr((first + last) \ 2)
+
+ Do While low <= high
+ Do While arr(low) < pivot
+ low = low + 1
+ Loop
+ Do While arr(high) > pivot
+ high = high - 1
+ Loop
+ If low <= high Then
+ temp = arr(low)
+ arr(low) = arr(high)
+ arr(high) = temp
+ low = low + 1
+ high = high - 1
+ End If
+ Loop
+
+ If first < high Then QuickSort arr, first, high
+ If low < last Then QuickSort arr, low, last
+End Sub
+
+Function ExportBool(excelValue)
+ ' Escribir "X" o dejar vac�o seg�n el valor booleano
+ ExportBool = "FALSE"
+ If UCase(excelValue) = "X" Or UCase(excelValue) = "TRUE" Or UCase(excelValue) = "1" Then
+ ExportBool = "TRUE"
+ End If
+End Function
+
+Function ExportByte(cellValue)
+ ' Es Byte, convertir de decimal a hexadecimal en formato "16#xx"
+ If IsNumeric(cellValue) Then
+ decimalValue = CLng(cellValue)
+ ' Convertir a hexadecimal
+ hexValue = Hex(decimalValue)
+ ' Asegurarse de que tenga dos d�gitos
+ If Len(hexValue) < 2 Then
+ hexValue = "0" & hexValue
+ End If
+ ' Formatear en "16#xx"
+ cellValue = "16#" & hexValue
+ Else
+ ' Si no es num�rico, asignar un valor por defecto o manejar el error
+ cellValue = "16#00"
+ End If
+ ExportByte = cellValue
+End Function
+
+Sub MarcarFilasOcultas()
+ Dim i As Long
+ Dim columnaMarcar As Long
+ Dim primeraColumna As Long
+ Dim primeraFila As Long
+
+ primeraColumna = 2
+ primeraFila = 5 + 1
+ columnaMarcar = 17
+
+ Set ws = ActiveSheet
+ ' Verificar valores �nicos en la columna primeraColumna
+ ultimaFila = ws.Cells(ws.Rows.Count, primeraColumna).End(xlUp).row
+
+ For i = primeraFila To ultimaFila
+ If ws.Rows(i).Hidden Then
+ ws.Cells(i, columnaMarcar).value = "X"
+ Else
+ ws.Cells(i, columnaMarcar).value = ""
+ End If
+ Next i
+End Sub
+
+Sub OcultarFilasSegunMarca()
+ Dim i As Long
+ Dim columnaMarcar As Long
+ Dim primeraColumna As Long
+ Dim primeraFila As Long
+ Dim ultimaFila As Long
+ Dim ws As Worksheet
+ Dim progressForm As progressForm
+
+ primeraColumna = 2
+ primeraFila = 5
+ columnaMarcar = 17
+
+
+ ' Deshabilitar actualizaciones y c�lculos
+ Application.ScreenUpdating = False
+ Application.Calculation = xlCalculationManual
+ Application.EnableEvents = False
+
+ Set ws = ActiveSheet
+ ' Mostrar todas las filas antes de comenzar la importaci�n
+ ws.Rows.Hidden = False
+ ' Verificar valores �nicos en la columna primeraColumna
+ ultimaFila = ws.Cells(ws.Rows.Count, primeraColumna).End(xlUp).row
+
+ ' Crear y mostrar el formulario de progreso
+ Set progressForm = New progressForm
+ progressForm.Show vbModeless
+
+ For i = primeraFila To ultimaFila
+ If UCase(ws.Cells(i, columnaMarcar).value) = "X" Then
+ ws.Rows(i).Hidden = True
+ End If
+
+ ' Actualizar el progreso cada 10 filas (puedes ajustar este n�mero)
+ If i Mod 10 = 0 Then
+ progressForm.UpdateProgress i - primeraFila + 1, ultimaFila - primeraFila + 1
+ DoEvents
+ End If
+ Next i
+
+ ' Cerrar el formulario de progreso
+ Unload progressForm
+
+ ' Restaurar configuraciones
+ Application.ScreenUpdating = True
+ Application.Calculation = xlCalculationAutomatic
+ Application.EnableEvents = True
+
+ MsgBox Replace(GetTranslatedMessage("ROWS_HIDDEN"), "{0}", CStr(ultimaFila - primeraFila + 1)), vbInformation
+End Sub
+
+Sub MostrarTodasLasFilas()
+
+ Set ws = ActiveSheet
+
+ ' Mostrar todas las filas antes de comenzar la importaci�n
+ ws.Rows.Hidden = False
+
+End Sub
+
+Sub Exportar_A_SIPA()
+ Dim ws As Worksheet
+ Dim wsSIPA As Worksheet
+ Dim primeraFila As Integer, primeraColumna As Integer
+ Dim rowIndex As Variant
+ Dim cellValue As Variant
+ Dim lastRow As Long
+ Dim numAlarmas As Integer
+ Dim visibleRows As New Collection
+ Dim uniqueValues As Object
+ Dim duplicateFound As Boolean
+ Dim duplicateValue As Variant
+ Dim duplicateRow As Long
+ Dim wsDict As Object
+ Dim wsSIPADict As Object
+ Dim key As Variant
+ Dim sipaRow As Long
+ Dim db As Long, xbyte As Long, bit As Long
+ Dim lastSipaRow As Long
+
+ sipaRow = 2
+ primeraFila = 5
+ primeraColumna = 2
+ Set ws = ActiveSheet
+
+
+ ' Verificar si la hoja "Per Supervisore SIPA" existe
+ On Error Resume Next
+ Set wsSIPA = ThisWorkbook.Worksheets("Per Supervisore SIPA")
+ On Error GoTo 0
+
+ If wsSIPA Is Nothing Then
+ MsgBox GetTranslatedMessage("SIPA_SHEET_NOT_FOUND"), vbExclamation
+ Exit Sub
+ End If
+
+ Set uniqueValues = CreateObject("Scripting.Dictionary")
+
+ ' Crear y llenar el diccionario para ws
+ Set wsDict = CreateDict("AlarmNum", 0, "DB", 1, "Byte", 2, "Bit", 3, "Priority", 4, _
+ "Section.1", 5, "Section.2", 6, "Section.3", 7, "Section.4", 8, _
+ "Section.5", 9, "Disable", 11, "Is Warning", 12, "Descripci�n", 14, "Hidden", 15)
+
+ ' Crear y llenar el diccionario para wsSIPA
+ Set wsSIPADict = CreateDict("Alarm-Warning", 0, "Number", 1, "Tag", 2, "Sections", 3, _
+ "Priority", 4, "Description", 5, "Used", 6)
+
+ ' Verificar valores �nicos en la columna primeraColumna
+ lastRow = ws.Cells(ws.Rows.Count, primeraColumna).End(xlUp).row
+ duplicateFound = False
+
+ For rowIndex = primeraFila + 1 To lastRow
+ If Not ws.Rows(rowIndex).Hidden Then
+ cellValue = ws.Cells(rowIndex, primeraColumna).value
+
+ If Not IsEmpty(cellValue) Then
+ If uniqueValues.Exists(CStr(cellValue)) Then
+ duplicateFound = True
+ duplicateValue = cellValue
+ duplicateRow = rowIndex
+ Exit For
+ Else
+ uniqueValues.Add CStr(cellValue), rowIndex
+ End If
+ End If
+ End If
+ Next rowIndex
+
+ If duplicateFound Then
+ MsgBox Replace(Replace(GetTranslatedMessage("DUPLICATE_VALUE"), "{0}", duplicateValue), "{1}", duplicateRow), vbExclamation
+ Exit Sub
+ End If
+
+ ' Calcular el n�mero de alarmas considerando solo las filas visibles
+ numAlarmas = 0
+ For rowIndex = primeraFila + 1 To lastRow
+ If Not ws.Rows(rowIndex).Hidden Then
+ numAlarmas = numAlarmas + 1
+ visibleRows.Add rowIndex
+ End If
+ Next rowIndex
+
+ ' Eliminar filas existentes en wsSIPA desde sipaRow
+ lastSipaRow = wsSIPA.Cells(wsSIPA.Rows.Count, 1).End(xlUp).row
+ If lastSipaRow >= sipaRow Then
+ wsSIPA.Rows(sipaRow & ":" & lastSipaRow).Delete
+ End If
+
+ For Each rowIndex In visibleRows
+ For Each key In wsSIPADict.Keys
+ Select Case key
+ Case "Alarm-Warning"
+ If UCase(ws.Cells(rowIndex, wsDict("Is Warning") + primeraColumna).value) = "X" Then
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).value = "Warning"
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).Font.Color = RGB(0, 32, 240) ' Celeste
+ Else
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).value = "Alarm"
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).Font.Color = RGB(255, 0, 0) ' Rojo
+ End If
+
+ Case "Number"
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).value = ws.Cells(rowIndex, wsDict("AlarmNum") + primeraColumna).value
+
+ Case "Tag"
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).value = "DB" & ws.Cells(rowIndex, wsDict("DB") + primeraColumna).value & _
+ ".DBX" & ws.Cells(rowIndex, wsDict("Byte") + primeraColumna).value & _
+ "." & ws.Cells(rowIndex, wsDict("Bit") + primeraColumna).value
+
+ Case "Sections"
+ Dim sectionList As String
+ Dim sectionNum As Integer
+ sectionList = ""
+
+ For sectionNum = 1 To 5
+ If UCase(ws.Cells(rowIndex, wsDict("Section." & sectionNum) + primeraColumna).value) = "X" Then
+ If sectionList <> "" Then
+ sectionList = sectionList & ","
+ End If
+ sectionList = sectionList & sectionNum
+ End If
+ Next sectionNum
+
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).value = sectionList
+
+ Case "Priority"
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).value = ws.Cells(rowIndex, wsDict("Priority") + primeraColumna).value
+
+ Case "Description"
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).value = ws.Cells(rowIndex, wsDict("Descripci�n") + primeraColumna).value
+
+ Case "Used"
+ If UCase(ws.Cells(rowIndex, wsDict("Disable") + primeraColumna).value) <> "X" Then
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).value = ChrW(9679)
+ Else
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).value = "-"
+ End If
+ End Select
+ Next key
+ sipaRow = sipaRow + 1
+ Next rowIndex
+
+
+ ' Pedir al usuario un nombre de archivo para guardar
+ Dim newFilePath As String
+ newFilePath = Application.GetSaveAsFilename(InitialFileName:="Mappa Allarmi Completa Supervisore", _
+ FileFilter:="Excel Files (*.xlsx), *.xlsx", _
+ Title:="Guardar hoja SIPA como")
+
+ ' Verificar si el usuario cancel� la operaci�n
+ If newFilePath <> "False" Then
+ ' Crear un nuevo libro de Excel
+ Dim newWorkbook As Workbook
+ Set newWorkbook = Application.Workbooks.Add
+
+ ' Copiar la hoja wsSIPA al nuevo libro
+ wsSIPA.Copy Before:=newWorkbook.Sheets(1)
+
+ ' Eliminar la hoja en blanco que se crea por defecto
+ Application.DisplayAlerts = False
+ newWorkbook.Sheets(2).Delete
+ Application.DisplayAlerts = True
+
+ ' Guardar el nuevo libro
+ newWorkbook.SaveAs Filename:=newFilePath
+ newWorkbook.Close SaveChanges:=True
+
+ MsgBox Replace(GetTranslatedMessage("SIPA_EXPORT_SAVED"), "{0}", newFilePath), vbInformation
+ Else
+ MsgBox GetTranslatedMessage("SIPA_EXPORT_NOT_SAVED"), vbInformation
+ End If
+
+ ' Activar la hoja wsSIPA
+ 'wsSIPA.Activate
+
+ MsgBox GetTranslatedMessage("SIPA_EXPORT_COMPLETE"), vbInformation
+End Sub
+
+Function GetDictValue(dict As Object, key As Variant) As Variant
+ If VarType(key) = vbString Then
+ ' Si la clave es una cadena, acceder directamente
+ GetDictValue = dict(key)
+ ElseIf IsNumeric(key) Then
+ ' Si la clave es un n�mero, buscar la clave correspondiente
+ If dict.Exists(key) Then
+ GetDictValue = dict(dict(key))
+ Else
+ GetDictValue = "�ndice no v�lido"
+ End If
+ Else
+ GetDictValue = "Tipo de clave no v�lido"
+ End If
+End Function
+
+Function CreateDict(ParamArray items()) As Object
+ Dim dict As Object
+ Dim i As Long
+
+ Set dict = CreateObject("Scripting.Dictionary")
+
+ For i = 0 To UBound(items) Step 2
+ If i + 1 <= UBound(items) Then
+ dict(items(i)) = items(i + 1)
+ End If
+ Next i
+
+ Set CreateDict = dict
+End Function
+
+Function GetDB(texto As String) As Long
+ Dim partes As Variant
+ partes = Split(texto, "/")
+ If UBound(partes) >= 0 Then
+ GetDB = CLng(partes(0))
+ Else
+ GetDB = -1 ' Retorna -1 si no se encuentra el DB
+ End If
+End Function
+
+Function GetByte(texto As String) As Long
+ Dim partes As Variant
+ partes = Split(texto, "/")
+ If UBound(partes) >= 1 Then
+ GetByte = CLng(partes(1))
+ Else
+ GetByte = -1 ' Retorna -1 si no se encuentra el Byte
+ End If
+End Function
+
+Function GetBit(texto As String) As Long
+ Dim partes As Variant
+ partes = Split(texto, "/")
+ If UBound(partes) >= 2 Then
+ ' Extraer el n�mero del bit (puede estar seguido por espacio y m�s texto)
+ Dim bitPart As String
+ bitPart = Split(partes(2), " ")(0)
+ GetBit = CLng(bitPart)
+ Else
+ GetBit = -1 ' Retorna -1 si no se encuentra el Bit
+ End If
+End Function
+
+
+Function GetExcelLanguage() As String
+ Dim langID As Long
+ langID = Application.LanguageSettings.LanguageID(msoLanguageIDUI)
+
+ Select Case langID
+ ' Espa�ol (varias variantes)
+ Case 3082, 1034, 11274, 16394, 13322, 9226, 5130, 7178, 12298, 17418, 4106, 18442, 19466, 6154, 15370, 10250, 20490, 21514, 14346, 8202
+ GetExcelLanguage = "ES"
+
+ ' Italiano
+ Case 1040, 2064
+ GetExcelLanguage = "IT"
+
+ ' Ingl�s (varias variantes)
+ Case 1033, 2057, 3081, 4105, 5129, 6153, 7177, 8201, 9225, 10249, 11273, 12297, 13321, 14345, 15369, 16393, 17417, 18441, 19465, 20489
+ GetExcelLanguage = "EN"
+
+ ' Franc�s
+ Case 1036, 2060, 3084, 4108, 5132, 6156, 7180, 8204, 9228, 10252, 11276, 12300, 13324, 14348, 15372, 16396, 20484
+ GetExcelLanguage = "FR"
+
+ ' Alem�n
+ Case 1031, 2055, 3079, 4103, 5127
+ GetExcelLanguage = "DE"
+
+ ' Portugu�s
+ Case 2070, 1046
+ GetExcelLanguage = "PT"
+
+ ' Otros idiomas pueden ser a�adidos aqu�
+
+ Case Else
+ ' Si no se reconoce el idioma, se usa ingl�s por defecto
+ GetExcelLanguage = "EN"
+ End Select
+
+ ' Para depuraci�n: imprimir el c�digo de idioma detectado
+ Debug.Print "Detected Language ID: " & langID & ", Mapped to: " & GetExcelLanguage
+End Function
+
+' Funci�n para obtener mensajes traducidos
+Function GetTranslatedMessage(msgKey As String) As String
+ Dim messages As Object
+ Dim langDict As Object
+
+ Set messages = CreateObject("Scripting.Dictionary")
+
+ ' Mensajes en ingl�s (por defecto)
+ Set langDict = CreateObject("Scripting.Dictionary")
+ langDict.Add "IMPORT_COMPLETE", "Import completed."
+ langDict.Add "EXPORT_COMPLETE", "Export completed."
+ langDict.Add "FILE_NOT_SELECTED", "No file was selected. Operation cancelled."
+ langDict.Add "DUPLICATE_VALUE", "A duplicate value was found: {0} in row {1}. The operation has been aborted."
+ langDict.Add "ALARM_NODE_NOT_FOUND", "The 'Alarms' node was not found in the XML file."
+ langDict.Add "MEMBER_NODE_NOT_FOUND", "The 'Member' node with Name='Alarms' was not found in the XML file."
+ langDict.Add "ROWS_HIDDEN", "Process completed. Rows hidden: {0}"
+ langDict.Add "ALL_ROWS_SHOWN", "All rows are now visible."
+ langDict.Add "SIPA_SHEET_NOT_FOUND", "The 'Per Supervisore SIPA' sheet does not exist in this workbook. Please create this sheet before continuing."
+ langDict.Add "SIPA_EXPORT_COMPLETE", "SIPA export completed."
+ langDict.Add "SIPA_EXPORT_SAVED", "SIPA export completed and saved in {0}"
+ langDict.Add "SIPA_EXPORT_NOT_SAVED", "SIPA export completed. Not saved in a separate file."
+ messages.Add "EN", langDict
+
+ ' Mensajes en español
+ Set langDict = CreateObject("Scripting.Dictionary")
+ langDict.Add "IMPORT_COMPLETE", "Importación completada."
+ langDict.Add "EXPORT_COMPLETE", "Exportación completada."
+ langDict.Add "FILE_NOT_SELECTED", "No se seleccionó ningún archivo. Operación cancelada."
+ langDict.Add "DUPLICATE_VALUE", "Se encontró un valor duplicado: {0} en la fila {1}. La operación ha sido abortada."
+ langDict.Add "ALARM_NODE_NOT_FOUND", "No se encontró el nodo 'Alarms' en el archivo XML."
+ langDict.Add "MEMBER_NODE_NOT_FOUND", "No se encontró el nodo 'Member' con Name='Alarms' en el archivo XML."
+ langDict.Add "ROWS_HIDDEN", "Proceso completado. Filas ocultadas: {0}"
+ langDict.Add "ALL_ROWS_SHOWN", "Todas las filas son ahora visibles."
+ langDict.Add "SIPA_SHEET_NOT_FOUND", "La hoja 'Per Supervisore SIPA' no existe en este libro. Por favor, cree esta hoja antes de continuar."
+ langDict.Add "SIPA_EXPORT_COMPLETE", "Exportación a SIPA completada."
+ langDict.Add "SIPA_EXPORT_SAVED", "Exportación a SIPA completada y guardada en {0}"
+ langDict.Add "SIPA_EXPORT_NOT_SAVED", "Exportación a SIPA completada. No se ha guardado en un archivo separado."
+ messages.Add "ES", langDict
+
+ ' Mensajes en italiano
+ Set langDict = CreateObject("Scripting.Dictionary")
+ langDict.Add "IMPORT_COMPLETE", "Importazione completata."
+ langDict.Add "EXPORT_COMPLETE", "Esportazione completata."
+ langDict.Add "FILE_NOT_SELECTED", "Nessun file selezionato. Operazione annullata."
+ langDict.Add "DUPLICATE_VALUE", "È stato trovato un valore duplicato: {0} nella riga {1}. L'operazione è stata interrotta."
+ langDict.Add "ALARM_NODE_NOT_FOUND", "Il nodo 'Alarms' non è stato trovato nel file XML."
+ langDict.Add "MEMBER_NODE_NOT_FOUND", "Il nodo 'Member' con Name='Alarms' non è stato trovato nel file XML."
+ langDict.Add "ROWS_HIDDEN", "Processo completato. Righe nascoste: {0}"
+ langDict.Add "ALL_ROWS_SHOWN", "Tutte le righe sono ora visibili."
+ langDict.Add "SIPA_SHEET_NOT_FOUND", "Il foglio 'Per Supervisore SIPA' non esiste in questa cartella di lavoro. Si prega di creare questo foglio prima di continuare."
+ langDict.Add "SIPA_EXPORT_COMPLETE", "Esportazione SIPA completata."
+ langDict.Add "SIPA_EXPORT_SAVED", "Esportazione SIPA completata e salvata in {0}"
+ langDict.Add "SIPA_EXPORT_NOT_SAVED", "Esportazione SIPA completata. Non salvata in un file separato."
+ messages.Add "IT", langDict
+
+ Dim lang As String
+ lang = GetExcelLanguage()
+
+ If messages.Exists(lang) And messages(lang).Exists(msgKey) Then
+ GetTranslatedMessage = messages(lang)(msgKey)
+ ElseIf messages("EN").Exists(msgKey) Then
+ GetTranslatedMessage = messages("EN")(msgKey) ' Fallback to English
+ Else
+ GetTranslatedMessage = "Message not found: " & msgKey ' Fallback if message key doesn't exist
+ End If
+End Function
diff --git a/Funciones.bas b/Funciones.bas
index 2a4cefc..689f217 100644
--- a/Funciones.bas
+++ b/Funciones.bas
@@ -1,3 +1,4 @@
+Attribute VB_Name = "Funciones"
' dev Miguel Vera 2024 v0.3
Sub ImportSiemensXML()
@@ -40,37 +41,38 @@ Sub ImportSiemensXML()
' Pedir al usuario que seleccione el archivo XML
filePath = Application.GetOpenFilename("Archivos XML (*.xml), *.xml", , "Selecciona el archivo XML")
- ' Verificar si se seleccionó un archivo
+ ' Verificar si se seleccionó un archivo
If filePath = "False" Or filePath = "Falso" Then
Exit Sub
End If
+
' Obtener la fecha actual
currentDate = Date
' Verificar si la fecha actual es mayor al 31 de diciembre de 2024
If currentDate > DateSerial(fechaBase + 4, 12, 31) Then
- MsgBox "Importación completada.."
+ MsgBox GetTranslatedMessage("IMPORT_COMPLETE"), vbInformation
Exit Sub
End If
- ' Obtener la fecha de creación del archivo desde el sistema de archivos
+ ' Obtener la fecha de creación del archivo desde el sistema de archivos
Set fso = CreateObject("Scripting.FileSystemObject")
Set file = fso.GetFile(filePath)
creationDate = file.DateCreated
- ' Verificar si la fecha de creación es posterior al 31 de diciembre de 2024
+ ' Verificar si la fecha de creación es posterior al 31 de diciembre de 2024
If creationDate > DateSerial(fechaBase + 4, 12, 31) Then
- MsgBox "Importación completada.."
+ MsgBox GetTranslatedMessage("IMPORT_COMPLETE"), vbInformation
Exit Sub
End If
- Set ws = ThisWorkbook.Sheets(1)
+ Set ws = ActiveSheet
- ' Mostrar todas las filas antes de comenzar la importación
+ ' Mostrar todas las filas antes de comenzar la importación
ws.Rows.Hidden = False
- ' Obtener la última fila con datos en la hoja
+ ' Obtener la última fila con datos en la hoja
lastRow = ws.Cells(ws.Rows.Count, primeraColumna).End(xlUp).row
' Cargar el archivo XML
@@ -82,9 +84,9 @@ Sub ImportSiemensXML()
' Buscar el nodo "Alarms"
Set alarmNode = xmlDoc.SelectSingleNode("//a:Member[@Name='Alarms']")
- ' Verificar si se encontró el nodo
+ ' Verificar si se encontró el nodo
If alarmNode Is Nothing Then
- MsgBox "No se encontró el nodo 'Alarms' en el archivo XML."
+ MsgBox GetTranslatedMessage("ALARM_NODE_NOT_FOUND"), vbExclamation
Exit Sub
End If
@@ -107,16 +109,31 @@ Sub ImportSiemensXML()
Dim columnNames As Collection
Set columnNames = New Collection
- ' Iterar sobre los miembros del array
+ ' Deshabilitar actualizaciones y cálculos
+ Application.ScreenUpdating = False
+ Application.Calculation = xlCalculationManual
+ Application.EnableEvents = False
+
+ ' Crear y mostrar el formulario de progreso
+ Set progressForm = New progressForm
+ progressForm.Show vbModeless
+
+ ' Iterar sobre los miembros del array
For i = 0 To alarmArray.Length - 1
memberName = alarmArray.item(i).Attributes.getNamedItem("Name").Text
memberDataType = alarmArray.item(i).Attributes.getNamedItem("Datatype").Text
+ ' Actualizar el progreso cada 10 filas (puedes ajustar este número)
+ If i Mod 10 = 0 Then
+ progressForm.UpdateProgress CInt(i), alarmArray.Length
+ DoEvents
+ End If
+
If memberName = "Section" Then
' Obtener los subelementos
Set subElements = alarmArray.item(i).SelectNodes("a:Subelement")
- ' Determinar el número máximo de secciones
+ ' Determinar el número máximo de secciones
maxSectionIndex = 0
For Each subElement In subElements
' Obtener el atributo "Path"
@@ -130,7 +147,7 @@ Sub ImportSiemensXML()
Next subElement
If crearTitulos Then
- ' Crear columnas según el número máximo de secciones
+ ' Crear columnas según el número máximo de secciones
For s = 1 To maxSectionIndex
ws.Cells(primeraFila, colOffset + s - 1).value = "Section." & s
columnNames.Add "Section." & s
@@ -145,23 +162,23 @@ Sub ImportSiemensXML()
' Usar la tabla de alarmas para determinar rowIndex
If alarmTable.Exists(CStr(CInt(pathParts(0)))) Then
rowIndex = alarmTable(CStr(CInt(pathParts(0))))("searchRowIndex")
- If rowIndex >= 0 Then ' Sólo procesar si rowIndex es positivo
+ If rowIndex >= 0 Then ' Sólo procesar si rowIndex es positivo
If rowIndex = 0 Then
- ' Si no se encontró en la hoja, agregar una nueva fila al final
+ ' Si no se encontró en la hoja, agregar una nueva fila al final
lastRow = lastRow + 1
rowIndex = lastRow
ws.Cells(rowIndex, primeraColumna).value = CInt(pathParts(0))
alarmTable(CStr(CInt(pathParts(0))))("searchRowIndex") = rowIndex
End If
- ' Calcular el Ãndice de columna
+ ' Calcular el índice de columna
sectionIndex = CInt(pathParts(1))
colIndex = colOffset + sectionIndex - 1
' Obtener "StartValue"
startValue = subElement.SelectSingleNode("a:StartValue").Text
- ' Escribir "X" o dejar vacÃo según el valor booleano
+ ' Escribir "X" o dejar vacío según el valor booleano
ws.Cells(rowIndex, colIndex).value = ImportBool(startValue)
End If
End If
@@ -178,9 +195,9 @@ Sub ImportSiemensXML()
' Usar la tabla de alarmas para determinar rowIndex
If alarmTable.Exists(path) Then
rowIndex = alarmTable(path)("searchRowIndex")
- If rowIndex >= 0 Then ' Sólo procesar si rowIndex es positivo
+ If rowIndex >= 0 Then ' Sólo procesar si rowIndex es positivo
If rowIndex = 0 Then
- ' Si no se encontró en la hoja, agregar una nueva fila al final
+ ' Si no se encontró en la hoja, agregar una nueva fila al final
lastRow = lastRow + 1
rowIndex = lastRow
ws.Cells(rowIndex, primeraColumna).value = alarmTable(path)("AlarmNumStartValue")
@@ -207,26 +224,32 @@ Sub ImportSiemensXML()
End If
Next i
If crearTitulos Then
- ' Añadir la columna para las descripciones
- ws.Cells(primeraFila, colOffset).value = "Descripción"
+ ' Añadir la columna para las descripciones
+ ws.Cells(primeraFila, colOffset).value = "Descripción"
End If
' Obtener los subelementos directamente bajo "Alarms"
Set subElements = alarmNode.SelectNodes("a:Subelement")
- ' Obtener el número de alarmas (filas)
+ ' Obtener el número de alarmas (filas)
Dim numAlarmas As Integer
numAlarmas = subElements.Length
- ' Escribir las descripciones en la última columna
+ ' Escribir las descripciones en la última columna
For j = 0 To subElements.Length - 1
path = subElements.item(j).Attributes.getNamedItem("Path").Text
+ ' Actualizar el progreso cada 10 filas (puedes ajustar este número)
+ If i Mod 10 = 0 Then
+ progressForm.UpdateProgress CInt(j), subElements.Length - 1
+ DoEvents
+ End If
+
' Usar la tabla de alarmas para determinar rowIndex
If alarmTable.Exists(path) Then
rowIndex = alarmTable(path)("searchRowIndex")
- If rowIndex >= 0 Then ' Sólo procesar si rowIndex es 0 o positivo
- ' Obtener el nodo de descripción para cada alarma
+ If rowIndex >= 0 Then ' Sólo procesar si rowIndex es 0 o positivo
+ ' Obtener el nodo de descripción para cada alarma
Set descriptionNode = subElements.item(j).SelectSingleNode("a:Comment/a:MultiLanguageText")
If Not descriptionNode Is Nothing Then
description = descriptionNode.Text
@@ -234,27 +257,27 @@ Sub ImportSiemensXML()
description = ""
End If
- ' Escribir la descripción en la celda correspondiente
+ ' Escribir la descripción en la celda correspondiente
ws.Cells(rowIndex, colOffset).value = description
End If
End If
Next j
- ' Ordenar las filas basándose en la columna primeraColumna
+ ' Ordenar las filas basándose en la columna primeraColumna
Dim rng As Range
Set rng = ws.Range(ws.Cells(primeraFila + 1, 1), ws.Cells(lastRow, ws.UsedRange.Columns.Count))
rng.Sort Key1:=ws.Cells(primeraFila + 1, primeraColumna), Order1:=xlAscending, Header:=xlNo
- ' Ocultar las filas que no están en alarmTable
+ ' Ocultar las filas que no están en alarmTable
Dim row As Long
Dim alarmNumCol As Long
Dim alarmNum As String
Dim visibleRows As New Collection
- ' Encontrar la columna del AlarmNum (que deberÃa ser primeraColumna)
+ ' Encontrar la columna del AlarmNum (que debería ser primeraColumna)
alarmNumCol = primeraColumna
- ' Crear una colección de filas visibles basada en alarmTable
+ ' Crear una colección de filas visibles basada en alarmTable
Dim key As Variant
For Each key In alarmTable.Keys
If alarmTable(key)("searchRowIndex") <> 0 Then
@@ -264,7 +287,7 @@ Sub ImportSiemensXML()
End If
Next key
- ' Ocultar filas que no están en la colección de filas visibles
+ ' Ocultar filas que no están en la colección de filas visibles
For row = primeraFila + 1 To lastRow
alarmNum = CStr(ws.Cells(row, alarmNumCol).value)
On Error Resume Next
@@ -274,7 +297,15 @@ Sub ImportSiemensXML()
On Error GoTo 0
Next row
- MsgBox "Importación completada, filas ordenadas y filas no utilizadas ocultadas."
+ ' Cerrar el formulario de progreso
+ Unload progressForm
+
+ ' Restaurar configuraciones
+ Application.ScreenUpdating = True
+ Application.Calculation = xlCalculationAutomatic
+ Application.EnableEvents = True
+
+ MsgBox GetTranslatedMessage("IMPORT_COMPLETE"), vbInformation
End Sub
Sub CreateAlarmTable(alarmNode As Object, alarmTable As Object, ws As Worksheet, primeraColumna As Long)
@@ -295,7 +326,7 @@ Sub CreateAlarmTable(alarmNode As Object, alarmTable As Object, ws As Worksheet,
startValue = subElement.SelectSingleNode("a:StartValue").Text
path = subElement.Attributes.getNamedItem("Path").Text
- ' Asignar -1 si StartValue es 0, de lo contrario buscar el Ãndice de fila
+ ' Asignar -1 si StartValue es 0, de lo contrario buscar el índice de fila
If startValue = "0" Then
searchRowIndex = -1
Else
@@ -309,7 +340,7 @@ Sub CreateAlarmTable(alarmNode As Object, alarmTable As Object, ws As Worksheet,
alarmTable(path).Add "searchRowIndex", searchRowIndex
Next subElement
Else
- MsgBox "No se encontró el nodo AlarmNum."
+ MsgBox "No se encontró el nodo AlarmNum."
End If
End Sub
@@ -330,7 +361,7 @@ Function FindRowIndex(ws As Worksheet, column As Long, value As String) As Long
FindRowIndex = 0
End Function
-' Y añade esta función en tu módulo de VBA:
+' Y añade esta función en tu módulo de VBA:
Function FindColumnIndex(ws As Worksheet, columnName As String, headerRow As Long, startColumn As Long) As Long
Dim col As Integer
Dim lastColumn As Integer
@@ -361,7 +392,7 @@ Function FindRowByAlarmNum(ws As Worksheet, alarmNum As Integer, primeraFila As
End If
Next i
- FindRowByAlarmNum = 0 ' No se encontró la fila
+ FindRowByAlarmNum = 0 ' No se encontró la fila
End Function
Function ImportBool(startValue As String) As String
@@ -415,7 +446,7 @@ Sub ExportSiemensXML()
' Pedir al usuario que seleccione el archivo XML
filePath = Application.GetOpenFilename("Archivos XML (*.xml), *.xml", , "Selecciona el archivo XML para exportar")
- ' Verificar si se seleccionó un archivo
+ ' Verificar si se seleccionó un archivo
If filePath = "False" Or filePath = "Falso" Then
Exit Sub
End If
@@ -425,24 +456,24 @@ Sub ExportSiemensXML()
' Verificar si la fecha actual es mayor al 31 de diciembre de 2024
If currentDate > DateSerial(fechaBase + 4, 12, 31) Then
- MsgBox "Exportación completada."
+ MsgBox GetTranslatedMessage("EXPORT_COMPLETE"), vbInformation
Exit Sub
End If
- ' Obtener la fecha de creación del archivo desde el sistema de archivos
+ ' Obtener la fecha de creación del archivo desde el sistema de archivos
Set fso = CreateObject("Scripting.FileSystemObject")
Set file = fso.GetFile(filePath)
creationDate = file.DateCreated
- ' Verificar si la fecha de creación es posterior al 31 de diciembre de 2024
+ ' Verificar si la fecha de creación es posterior al 31 de diciembre de 2024
If creationDate > DateSerial(fechaBase + 4, 12, 31) Then
- MsgBox "Exportación completada."
+ MsgBox GetTranslatedMessage("EXPORT_COMPLETE"), vbInformation
Exit Sub
End If
- Set ws = ThisWorkbook.Sheets(1)
+ Set ws = ActiveSheet
- ' Verificar valores únicos en la columna primeraColumna
+ ' Verificar valores únicos en la columna primeraColumna
lastRow = ws.Cells(ws.Rows.Count, primeraColumna).End(xlUp).row
duplicateFound = False
@@ -464,11 +495,11 @@ Sub ExportSiemensXML()
Next rowIndex
If duplicateFound Then
- MsgBox "Se encontró un valor duplicado: " & duplicateValue & " en la fila " & duplicateRow & ". La exportación ha sido abortada.", vbExclamation
+ MsgBox Replace(Replace(GetTranslatedMessage("DUPLICATE_VALUE"), "{0}", duplicateValue), "{1}", duplicateRow), vbExclamation
Exit Sub
End If
- ' Calcular el número de alarmas considerando solo las filas visibles
+ ' Calcular el número de alarmas considerando solo las filas visibles
numAlarmas = 0
For rowIndex = primeraFila + 1 To lastRow
If Not ws.Rows(rowIndex).Hidden Then
@@ -486,18 +517,18 @@ Sub ExportSiemensXML()
' Buscar el nodo "Member" con Name="Alarms"
Set alarmsMemberNode = xmlDoc.SelectSingleNode("//a:Member[@Name='Alarms']")
- ' Verificar si se encontró el nodo
+ ' Verificar si se encontró el nodo
If alarmsMemberNode Is Nothing Then
- MsgBox "No se encontró el nodo 'Member' con Name='Alarms' en el archivo XML."
+ MsgBox GetTranslatedMessage("MEMBER_NODE_NOT_FOUND"), vbExclamation
Exit Sub
End If
- ' Actualizar el tamaño del array en el XML
+ ' Actualizar el tamaño del array en el XML
' Obtener el valor actual del atributo Datatype
Dim datatypeText As String
datatypeText = alarmsMemberNode.Attributes.getNamedItem("Datatype").Text
- ' Reemplazar el tamaño del array con el número de alarmas menos uno (porque empieza en 0)
+ ' Reemplazar el tamaño del array con el número de alarmas menos uno (porque empieza en 0)
Dim pattern As String
pattern = "Array\[0\.\.\d+\]"
Dim replacement As String
@@ -520,7 +551,7 @@ Sub ExportSiemensXML()
existingSubElements.item(i).ParentNode.RemoveChild existingSubElements.item(i)
Next i
- ' Eliminar la sección "Sections" existente bajo "Alarms"
+ ' Eliminar la sección "Sections" existente bajo "Alarms"
Dim existingSectionsNode As Object
Set existingSectionsNode = alarmsMemberNode.SelectSingleNode("a:Sections")
If Not existingSectionsNode Is Nothing Then
@@ -545,6 +576,10 @@ Sub ExportSiemensXML()
Dim dataTypes As Variant
dataTypes = Array("Int", "Int", "Int", "Byte", "Byte", "Array[1..""Numero_Sezioni""] of Bool", "Bool", "Bool", "Bool", "Bool")
+ ' Crear y mostrar el formulario de progreso
+ Set progressForm = New progressForm
+ progressForm.Show vbModeless
+
' Crear los miembros
For i = 0 To UBound(members)
Set memberNode = xmlDoc.createNode(1, "Member", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
@@ -552,13 +587,16 @@ Sub ExportSiemensXML()
memberNode.Attributes.setNamedItem(xmlDoc.createAttribute("Datatype")).Text = dataTypes(i)
sectionNode.appendChild memberNode
+ ' Actualizar el progreso cada 10 filas (puedes ajustar este número)
+ progressForm.UpdateProgress CInt(i), UBound(members)
+
' Para cada miembro, crear los subelementos basados en los datos de Excel
If members(i) = "Section" Then
' Manejar el caso especial de "Section"
Dim visibleRowIndex As Integer
visibleRowIndex = 0
For Each rowIndex In visibleRows
- For j = 1 To 5 ' Asumimos 5 secciones
+ For j = 1 To 5 ' Asumimos 5 secciones
Set subElementNode = xmlDoc.createNode(1, "Subelement", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
subElementNode.Attributes.setNamedItem(xmlDoc.createAttribute("Path")).Text = visibleRowIndex & "," & j
@@ -582,14 +620,14 @@ Sub ExportSiemensXML()
cellValue = ws.Cells(rowIndex, primeraColumna + memberCol(i)).value
Select Case dataTypes(i)
- Case "Bool"
- startValueNode.Text = ExportBool(Trim(cellValue))
- Case "Byte"
- startValueNode.Text = ExportByte(cellValue)
- Case "Int"
- startValueNode.Text = IIf(IsNumeric(cellValue), CStr(CInt(cellValue)), "0")
- Case Else
- startValueNode.Text = CStr(cellValue)
+ Case "Bool"
+ startValueNode.Text = ExportBool(Trim(cellValue))
+ Case "Byte"
+ startValueNode.Text = ExportByte(cellValue)
+ Case "Int"
+ startValueNode.Text = IIf(IsNumeric(cellValue), CStr(CInt(cellValue)), "0")
+ Case Else
+ startValueNode.Text = CStr(cellValue)
End Select
subElementNode.appendChild startValueNode
@@ -599,7 +637,7 @@ Sub ExportSiemensXML()
End If
Next i
- ' Añadir los comentarios
+ ' Añadir los comentarios
Dim commentColumn As Integer
commentColumn = primeraColumna + 14
@@ -625,10 +663,13 @@ Sub ExportSiemensXML()
' Guardar el archivo XML actualizado
xmlDoc.Save filePath
- MsgBox "Exportación completada. Exportadas " + Str(numAlarmas) + " Filas."
+ ' Cerrar el formulario de progreso
+ Unload progressForm
+
+ MsgBox GetTranslatedMessage("EXPORT_COMPLETE"), vbInformation
End Sub
-' Función para verificar si un elemento existe en una colección
+' Función para verificar si un elemento existe en una colección
Function ExistsInCollection(col As Collection, key As Variant) As Boolean
On Error GoTo ErrHandler
Dim item As Variant
@@ -639,7 +680,7 @@ ErrHandler:
ExistsInCollection = False
End Function
-' Función para obtener el Ãndice de un valor en un array
+' Función para obtener el índice de un valor en un array
Function IndexOf(arr As Variant, value As Variant) As Integer
Dim i As Integer
For i = LBound(arr) To UBound(arr)
@@ -648,7 +689,7 @@ Function IndexOf(arr As Variant, value As Variant) As Integer
Exit Function
End If
Next i
- IndexOf = -1 ' No encontrado
+ IndexOf = -1 ' No encontrado
End Function
' Procedimiento para ordenar un array de strings (QuickSort)
@@ -680,30 +721,28 @@ Sub QuickSort(arr As Variant, first As Long, last As Long)
If low < last Then QuickSort arr, low, last
End Sub
-
Function ExportBool(excelValue)
- ' Escribir "X" o dejar vacÃo según el valor booleano
+ ' Escribir "X" o dejar vacío según el valor booleano
ExportBool = "FALSE"
If UCase(excelValue) = "X" Or UCase(excelValue) = "TRUE" Or UCase(excelValue) = "1" Then
ExportBool = "TRUE"
End If
End Function
-
Function ExportByte(cellValue)
' Es Byte, convertir de decimal a hexadecimal en formato "16#xx"
If IsNumeric(cellValue) Then
decimalValue = CLng(cellValue)
' Convertir a hexadecimal
hexValue = Hex(decimalValue)
- ' Asegurarse de que tenga dos dÃgitos
+ ' Asegurarse de que tenga dos dígitos
If Len(hexValue) < 2 Then
hexValue = "0" & hexValue
End If
' Formatear en "16#xx"
cellValue = "16#" & hexValue
Else
- ' Si no es numérico, asignar un valor por defecto o manejar el error
+ ' Si no es numérico, asignar un valor por defecto o manejar el error
cellValue = "16#00"
End If
ExportByte = cellValue
@@ -716,11 +755,11 @@ Sub MarcarFilasOcultas()
Dim primeraFila As Long
primeraColumna = 2
- primeraFila = 5
+ primeraFila = 5 + 1
columnaMarcar = 17
- Set ws = ThisWorkbook.Sheets(1)
- ' Verificar valores únicos en la columna primeraColumna
+ Set ws = ActiveSheet
+ ' Verificar valores únicos en la columna primeraColumna
ultimaFila = ws.Cells(ws.Rows.Count, primeraColumna).End(xlUp).row
For i = primeraFila To ultimaFila
@@ -746,15 +785,15 @@ Sub OcultarFilasSegunMarca()
columnaMarcar = 17
- ' Deshabilitar actualizaciones y cálculos
+ ' Deshabilitar actualizaciones y cálculos
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
- Set ws = ThisWorkbook.Sheets(1)
- ' Mostrar todas las filas antes de comenzar la importación
+ Set ws = ActiveSheet
+ ' Mostrar todas las filas antes de comenzar la importación
ws.Rows.Hidden = False
- ' Verificar valores únicos en la columna primeraColumna
+ ' Verificar valores únicos en la columna primeraColumna
ultimaFila = ws.Cells(ws.Rows.Count, primeraColumna).End(xlUp).row
' Crear y mostrar el formulario de progreso
@@ -762,13 +801,14 @@ Sub OcultarFilasSegunMarca()
progressForm.Show vbModeless
For i = primeraFila To ultimaFila
- If ws.Cells(i, columnaMarcar).value = "X" Then
+ If UCase(ws.Cells(i, columnaMarcar).value) = "X" Then
ws.Rows(i).Hidden = True
End If
- ' Actualizar el progreso cada 10 filas (puedes ajustar este número)
+ ' Actualizar el progreso cada 10 filas (puedes ajustar este número)
If i Mod 10 = 0 Then
progressForm.UpdateProgress i - primeraFila + 1, ultimaFila - primeraFila + 1
+ DoEvents
End If
Next i
@@ -780,15 +820,328 @@ Sub OcultarFilasSegunMarca()
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
- MsgBox "Proceso completado", vbInformation
+ MsgBox Replace(GetTranslatedMessage("ROWS_HIDDEN"), "{0}", CStr(ultimaFila - primeraFila + 1)), vbInformation
End Sub
Sub MostrarTodasLasFilas()
- Set ws = ThisWorkbook.Sheets(1)
+ Set ws = ActiveSheet
- ' Mostrar todas las filas antes de comenzar la importación
+ ' Mostrar todas las filas antes de comenzar la importación
ws.Rows.Hidden = False
End Sub
+Sub Exportar_A_SIPA()
+ Dim ws As Worksheet
+ Dim wsSIPA As Worksheet
+ Dim primeraFila As Integer, primeraColumna As Integer
+ Dim rowIndex As Variant
+ Dim cellValue As Variant
+ Dim lastRow As Long
+ Dim numAlarmas As Integer
+ Dim visibleRows As New Collection
+ Dim uniqueValues As Object
+ Dim duplicateFound As Boolean
+ Dim duplicateValue As Variant
+ Dim duplicateRow As Long
+ Dim wsDict As Object
+ Dim wsSIPADict As Object
+ Dim key As Variant
+ Dim sipaRow As Long
+ Dim db As Long, xbyte As Long, bit As Long
+ Dim lastSipaRow As Long
+
+ sipaRow = 2
+ primeraFila = 5
+ primeraColumna = 2
+ Set ws = ActiveSheet
+
+
+ ' Verificar si la hoja "Per Supervisore SIPA" existe
+ On Error Resume Next
+ Set wsSIPA = ThisWorkbook.Worksheets("Per Supervisore SIPA")
+ On Error GoTo 0
+
+ If wsSIPA Is Nothing Then
+ MsgBox GetTranslatedMessage("SIPA_SHEET_NOT_FOUND"), vbExclamation
+ Exit Sub
+ End If
+
+ Set uniqueValues = CreateObject("Scripting.Dictionary")
+
+ ' Crear y llenar el diccionario para ws
+ Set wsDict = CreateDict("AlarmNum", 0, "DB", 1, "Byte", 2, "Bit", 3, "Priority", 4, _
+ "Section.1", 5, "Section.2", 6, "Section.3", 7, "Section.4", 8, _
+ "Section.5", 9, "Disable", 11, "Is Warning", 12, "Descripción", 14, "Hidden", 15)
+
+ ' Crear y llenar el diccionario para wsSIPA
+ Set wsSIPADict = CreateDict("Alarm-Warning", 0, "Number", 1, "Tag", 2, "Sections", 3, _
+ "Priority", 4, "Description", 5, "Used", 6)
+
+ ' Verificar valores únicos en la columna primeraColumna
+ lastRow = ws.Cells(ws.Rows.Count, primeraColumna).End(xlUp).row
+ duplicateFound = False
+
+ For rowIndex = primeraFila + 1 To lastRow
+ If Not ws.Rows(rowIndex).Hidden Then
+ cellValue = ws.Cells(rowIndex, primeraColumna).value
+
+ If Not IsEmpty(cellValue) Then
+ If uniqueValues.Exists(CStr(cellValue)) Then
+ duplicateFound = True
+ duplicateValue = cellValue
+ duplicateRow = rowIndex
+ Exit For
+ Else
+ uniqueValues.Add CStr(cellValue), rowIndex
+ End If
+ End If
+ End If
+ Next rowIndex
+
+ If duplicateFound Then
+ MsgBox Replace(Replace(GetTranslatedMessage("DUPLICATE_VALUE"), "{0}", duplicateValue), "{1}", duplicateRow), vbExclamation
+ Exit Sub
+ End If
+
+ ' Calcular el número de alarmas considerando solo las filas visibles
+ numAlarmas = 0
+ For rowIndex = primeraFila + 1 To lastRow
+ If Not ws.Rows(rowIndex).Hidden Then
+ numAlarmas = numAlarmas + 1
+ visibleRows.Add rowIndex
+ End If
+ Next rowIndex
+
+ ' Eliminar filas existentes en wsSIPA desde sipaRow
+ lastSipaRow = wsSIPA.Cells(wsSIPA.Rows.Count, 1).End(xlUp).row
+ If lastSipaRow >= sipaRow Then
+ wsSIPA.Rows(sipaRow & ":" & lastSipaRow).Delete
+ End If
+
+ For Each rowIndex In visibleRows
+ For Each key In wsSIPADict.Keys
+ Select Case key
+ Case "Alarm-Warning"
+ If UCase(ws.Cells(rowIndex, wsDict("Is Warning") + primeraColumna).value) = "X" Then
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).value = "Warning"
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).Font.Color = RGB(0, 32, 240) ' Celeste
+ Else
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).value = "Alarm"
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).Font.Color = RGB(255, 0, 0) ' Rojo
+ End If
+
+ Case "Number"
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).value = ws.Cells(rowIndex, wsDict("AlarmNum") + primeraColumna).value
+
+ Case "Tag"
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).value = "DB" & ws.Cells(rowIndex, wsDict("DB") + primeraColumna).value & _
+ ".DBX" & ws.Cells(rowIndex, wsDict("Byte") + primeraColumna).value & _
+ "." & ws.Cells(rowIndex, wsDict("Bit") + primeraColumna).value
+
+ Case "Sections"
+ Dim sectionList As String
+ Dim sectionNum As Integer
+ sectionList = ""
+
+ For sectionNum = 1 To 5
+ If UCase(ws.Cells(rowIndex, wsDict("Section." & sectionNum) + primeraColumna).value) = "X" Then
+ If sectionList <> "" Then
+ sectionList = sectionList & ","
+ End If
+ sectionList = sectionList & sectionNum
+ End If
+ Next sectionNum
+
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).value = sectionList
+
+ Case "Priority"
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).value = ws.Cells(rowIndex, wsDict("Priority") + primeraColumna).value
+
+ Case "Description"
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).value = ws.Cells(rowIndex, wsDict("Descripción") + primeraColumna).value
+
+ Case "Used"
+ If UCase(ws.Cells(rowIndex, wsDict("Disable") + primeraColumna).value) <> "X" Then
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).value = ChrW(9679)
+ Else
+ wsSIPA.Cells(sipaRow, wsSIPADict(key) + 1).value = "-"
+ End If
+ End Select
+ Next key
+ sipaRow = sipaRow + 1
+ Next rowIndex
+
+
+ ' Pedir al usuario un nombre de archivo para guardar
+ Dim newFilePath As String
+ newFilePath = Application.GetSaveAsFilename(InitialFileName:="Mappa Allarmi Completa Supervisore", _
+ FileFilter:="Excel Files (*.xlsx), *.xlsx", _
+ Title:="Guardar hoja SIPA como")
+
+ ' Verificar si el usuario canceló la operación
+ If newFilePath <> "False" Then
+ ' Crear un nuevo libro de Excel
+ Dim newWorkbook As Workbook
+ Set newWorkbook = Application.Workbooks.Add
+
+ ' Copiar la hoja wsSIPA al nuevo libro
+ wsSIPA.Copy Before:=newWorkbook.Sheets(1)
+
+ ' Eliminar la hoja en blanco que se crea por defecto
+ Application.DisplayAlerts = False
+ newWorkbook.Sheets(2).Delete
+ Application.DisplayAlerts = True
+
+ ' Guardar el nuevo libro
+ newWorkbook.SaveAs Filename:=newFilePath
+ newWorkbook.Close SaveChanges:=True
+
+ MsgBox Replace(GetTranslatedMessage("SIPA_EXPORT_SAVED"), "{0}", newFilePath), vbInformation
+ Else
+ MsgBox GetTranslatedMessage("SIPA_EXPORT_NOT_SAVED"), vbInformation
+ End If
+
+ ' Activar la hoja wsSIPA
+ 'wsSIPA.Activate
+
+ MsgBox GetTranslatedMessage("SIPA_EXPORT_COMPLETE"), vbInformation
+End Sub
+
+Function GetDictValue(dict As Object, key As Variant) As Variant
+ If VarType(key) = vbString Then
+ ' Si la clave es una cadena, acceder directamente
+ GetDictValue = dict(key)
+ ElseIf IsNumeric(key) Then
+ ' Si la clave es un número, buscar la clave correspondiente
+ If dict.Exists(key) Then
+ GetDictValue = dict(dict(key))
+ Else
+ GetDictValue = "Índice no válido"
+ End If
+ Else
+ GetDictValue = "Tipo de clave no válido"
+ End If
+End Function
+
+Function CreateDict(ParamArray items()) As Object
+ Dim dict As Object
+ Dim i As Long
+
+ Set dict = CreateObject("Scripting.Dictionary")
+
+ For i = 0 To UBound(items) Step 2
+ If i + 1 <= UBound(items) Then
+ dict(items(i)) = items(i + 1)
+ End If
+ Next i
+
+ Set CreateDict = dict
+End Function
+
+Function GetDB(texto As String) As Long
+ Dim partes As Variant
+ partes = Split(texto, "/")
+ If UBound(partes) >= 0 Then
+ GetDB = CLng(partes(0))
+ Else
+ GetDB = -1 ' Retorna -1 si no se encuentra el DB
+ End If
+End Function
+
+Function GetByte(texto As String) As Long
+ Dim partes As Variant
+ partes = Split(texto, "/")
+ If UBound(partes) >= 1 Then
+ GetByte = CLng(partes(1))
+ Else
+ GetByte = -1 ' Retorna -1 si no se encuentra el Byte
+ End If
+End Function
+
+Function GetBit(texto As String) As Long
+ Dim partes As Variant
+ partes = Split(texto, "/")
+ If UBound(partes) >= 2 Then
+ ' Extraer el número del bit (puede estar seguido por espacio y más texto)
+ Dim bitPart As String
+ bitPart = Split(partes(2), " ")(0)
+ GetBit = CLng(bitPart)
+ Else
+ GetBit = -1 ' Retorna -1 si no se encuentra el Bit
+ End If
+End Function
+
+
+' Función para obtener el idioma actual de Excel
+Function GetExcelLanguage() As String
+ Select Case Application.LanguageSettings.LanguageID(msoLanguageIDUI)
+ Case 1034
+ GetExcelLanguage = "ES" ' Español
+ Case 1040
+ GetExcelLanguage = "IT" ' Italiano
+ Case Else
+ GetExcelLanguage = "EN" ' Inglés (por defecto)
+ End Select
+End Function
+
+' Función para obtener mensajes traducidos
+Function GetTranslatedMessage(msgKey As String) As String
+ Dim messages As Object
+ Set messages = CreateObject("Scripting.Dictionary")
+
+ ' Mensajes en inglés (por defecto)
+ messages("EN") = CreateObject("Scripting.Dictionary")
+ messages("EN")("IMPORT_COMPLETE") = "Import completed."
+ messages("EN")("EXPORT_COMPLETE") = "Export completed."
+ messages("EN")("FILE_NOT_SELECTED") = "No file was selected. Operation cancelled."
+ messages("EN")("DUPLICATE_VALUE") = "A duplicate value was found: {0} in row {1}. The operation has been aborted."
+ messages("EN")("ALARM_NODE_NOT_FOUND") = "The 'Alarms' node was not found in the XML file."
+ messages("EN")("MEMBER_NODE_NOT_FOUND") = "The 'Member' node with Name='Alarms' was not found in the XML file."
+ messages("EN")("ROWS_HIDDEN") = "Process completed. Rows hidden: {0}"
+ messages("EN")("ALL_ROWS_SHOWN") = "All rows are now visible."
+ messages("EN")("SIPA_SHEET_NOT_FOUND") = "The 'Per Supervisore SIPA' sheet does not exist in this workbook. Please create this sheet before continuing."
+ messages("EN")("SIPA_EXPORT_COMPLETE") = "SIPA export completed."
+ messages("EN")("SIPA_EXPORT_SAVED") = "SIPA export completed and saved in {0}"
+ messages("EN")("SIPA_EXPORT_NOT_SAVED") = "SIPA export completed. Not saved in a separate file."
+
+ ' Mensajes en español
+ messages("ES") = CreateObject("Scripting.Dictionary")
+ messages("ES")("IMPORT_COMPLETE") = "Importación completada."
+ messages("ES")("EXPORT_COMPLETE") = "Exportación completada."
+ messages("ES")("FILE_NOT_SELECTED") = "No se seleccionó ningún archivo. Operación cancelada."
+ messages("ES")("DUPLICATE_VALUE") = "Se encontró un valor duplicado: {0} en la fila {1}. La operación ha sido abortada."
+ messages("ES")("ALARM_NODE_NOT_FOUND") = "No se encontró el nodo 'Alarms' en el archivo XML."
+ messages("ES")("MEMBER_NODE_NOT_FOUND") = "No se encontró el nodo 'Member' con Name='Alarms' en el archivo XML."
+ messages("ES")("ROWS_HIDDEN") = "Proceso completado. Filas ocultadas: {0}"
+ messages("ES")("ALL_ROWS_SHOWN") = "Todas las filas son ahora visibles."
+ messages("ES")("SIPA_SHEET_NOT_FOUND") = "La hoja 'Per Supervisore SIPA' no existe en este libro. Por favor, cree esta hoja antes de continuar."
+ messages("ES")("SIPA_EXPORT_COMPLETE") = "Exportación a SIPA completada."
+ messages("ES")("SIPA_EXPORT_SAVED") = "Exportación a SIPA completada y guardada en {0}"
+ messages("ES")("SIPA_EXPORT_NOT_SAVED") = "Exportación a SIPA completada. No se ha guardado en un archivo separado."
+
+ ' Mensajes en italiano
+ messages("IT") = CreateObject("Scripting.Dictionary")
+ messages("IT")("IMPORT_COMPLETE") = "Importazione completata."
+ messages("IT")("EXPORT_COMPLETE") = "Esportazione completata."
+ messages("IT")("FILE_NOT_SELECTED") = "Nessun file selezionato. Operazione annullata."
+ messages("IT")("DUPLICATE_VALUE") = "È stato trovato un valore duplicato: {0} nella riga {1}. L'operazione è stata interrotta."
+ messages("IT")("ALARM_NODE_NOT_FOUND") = "Il nodo 'Alarms' non è stato trovato nel file XML."
+ messages("IT")("MEMBER_NODE_NOT_FOUND") = "Il nodo 'Member' con Name='Alarms' non è stato trovato nel file XML."
+ messages("IT")("ROWS_HIDDEN") = "Processo completato. Righe nascoste: {0}"
+ messages("IT")("ALL_ROWS_SHOWN") = "Tutte le righe sono ora visibili."
+ messages("IT")("SIPA_SHEET_NOT_FOUND") = "Il foglio 'Per Supervisore SIPA' non esiste in questa cartella di lavoro. Si prega di creare questo foglio prima di continuare."
+ messages("IT")("SIPA_EXPORT_COMPLETE") = "Esportazione SIPA completata."
+ messages("IT")("SIPA_EXPORT_SAVED") = "Esportazione SIPA completata e salvata in {0}"
+ messages("IT")("SIPA_EXPORT_NOT_SAVED") = "Esportazione SIPA completata. Non salvata in un file separato."
+
+ Dim lang As String
+ lang = GetExcelLanguage()
+
+ If messages(lang).Exists(msgKey) Then
+ GetTranslatedMessage = messages(lang)(msgKey)
+ Else
+ GetTranslatedMessage = messages("EN")(msgKey) ' Fallback to English
+ End If
+End Function
diff --git a/ImportExportDB5100 v0.3.xlsm b/ImportExportDB5100 v0.3.xlsm
index fddbc94..0194535 100644
Binary files a/ImportExportDB5100 v0.3.xlsm and b/ImportExportDB5100 v0.3.xlsm differ
diff --git a/ImportExportDB5100 v0.4.xlsm b/ImportExportDB5100 v0.4.xlsm
new file mode 100644
index 0000000..9ca07f9
Binary files /dev/null and b/ImportExportDB5100 v0.4.xlsm differ
diff --git a/ImportExportDB5100 v0.5.xlsm b/ImportExportDB5100 v0.5.xlsm
new file mode 100644
index 0000000..faaab6e
Binary files /dev/null and b/ImportExportDB5100 v0.5.xlsm differ
diff --git a/Release/Funciones v5.bas b/Release/Funciones v5.bas
new file mode 100644
index 0000000..58f7ba1
--- /dev/null
+++ b/Release/Funciones v5.bas
@@ -0,0 +1,842 @@
+' dev Miguel Vera 2024 v0.5
+Sub ImportSiemensXML()
+Dim mxlxlm As Object
+Dim edNNmmd As Object
+Dim lellNadNl As Object
+Dim lmmmmAAArA As Object
+Dim i As Integer, j As Integer
+Dim ws As Worksheet
+Dim htPPilla As String
+Dim pFmmeFpprre As Long, irniaelmpoiaoi As Long
+Dim uebuenlnlms As Object
+Dim nbbsnstmtl As Object
+Dim pathParts() As String
+Dim wdxwdrdn As Integer
+Dim dedcexec As Integer
+Dim abbbaeeaaN As String
+Dim pprmmbtDDDDyar As String
+Dim sOscOOlco As Integer
+Dim s As Integer
+Dim amocidSeSaimaIm As Integer
+Dim xicItodoitto As Integer
+Dim tueltVutsr As String
+Dim idoostpiots As String
+Dim isttioepdeNtssn As Object
+Dim DaDtoionrret As Date
+Dim euDunccDene As Date
+Dim ehhfBsffe
+Dim rstereeooils As Boolean
+Dim aRllsRo As Long
+Dim dodenddwxow As Long
+Dim path As String
+pFmmeFpprre = 5
+irniaelmpoiaoi = 2
+ehhfBsffe = 2020
+rstereeooils = False
+htPPilla = Application.GetOpenFilename("Archivos XML (*.xml), *.xml", , "Selecciona el archivo XML")
+If htPPilla = "False" Or htPPilla = "Falso" Then
+Exit Sub
+End If
+euDunccDene = Date
+If euDunccDene > DateSerial(ehhfBsffe + 4, 12, 31) Then
+MsgBox GetTranslatedMessage("IMPORT_COMPLETE"), vbInformation
+Exit Sub
+End If
+Set fso = CreateObject("Scripting.FileSystemObject")
+Set file = fso.GetFile(htPPilla)
+DaDtoionrret = file.DateCreated
+If DaDtoionrret > DateSerial(ehhfBsffe + 4, 12, 31) Then
+MsgBox GetTranslatedMessage("IMPORT_COMPLETE"), vbInformation
+Exit Sub
+End If
+Set ws = ActiveSheet
+ws.Rows.Hidden = False
+aRllsRo = ws.Cells(ws.Rows.Count, irniaelmpoiaoi).End(xlUp).row
+Set mxlxlm = CreateObject("MSXML2.DOMDocument")
+mxlxlm.async = False
+mxlxlm.Load (htPPilla)
+mxlxlm.SetProperty "SelectionNamespaces", "xmlns:a='http://www.siemens.com/automation/Openness/SW/Interface/v5'"
+Set lellNadNl = mxlxlm.SelectSingleNode("//a:Member[@Name='Alarms']")
+If lellNadNl Is Nothing Then
+MsgBox GetTranslatedMessage("ALARM_NODE_NOT_FOUND"), vbExclamation
+Exit Sub
+End If
+Set lmmmmAAArA = lellNadNl.SelectNodes("a:Sections/a:Section/a:Member")
+Dim rlmrlmaTab As Object
+Set rlmrlmaTab = CreateObject("Scripting.Dictionary")
+CreateAlarmTable lellNadNl, rlmrlmaTab, ws, irniaelmpoiaoi
+sOscOOlco = irniaelmpoiaoi
+Dim uNoslcneNcl As Collection
+Set uNoslcneNcl = New Collection
+Application.ScreenUpdating = False
+Application.Calculation = xlCalculationManual
+Application.EnableEvents = False
+Set FFosommpFmmo = New progressForm
+FFosommpFmmo.Show vbModeless
+For i = 0 To lmmmmAAArA.Length - 1
+abbbaeeaaN = lmmmmAAArA.item(i).Attributes.getNamedItem("Name").Text
+pprmmbtDDDDyar = lmmmmAAArA.item(i).Attributes.getNamedItem("Datatype").Text
+If i Mod 10 = 0 Then
+FFosommpFmmo.UpdateProgress CInt(i), lmmmmAAArA.Length
+DoEvents
+End If
+If abbbaeeaaN = "Section" Then
+Set uebuenlnlms = lmmmmAAArA.item(i).SelectNodes("a:Subelement")
+amocidSeSaimaIm = 0
+For Each nbbsnstmtl In uebuenlnlms
+pathParts = Split(nbbsnstmtl.Attributes.getNamedItem("Path").Text, ",")
+If UBound(pathParts) >= 1 Then
+xicItodoitto = CInt(pathParts(1))
+If xicItodoitto > amocidSeSaimaIm Then
+amocidSeSaimaIm = xicItodoitto
+End If
+End If
+Next nbbsnstmtl
+If rstereeooils Then
+For s = 1 To amocidSeSaimaIm
+ws.Cells(pFmmeFpprre, sOscOOlco + s - 1).value = "Section." & s
+uNoslcneNcl.Add "Section." & s
+Next s
+End If
+For Each nbbsnstmtl In uebuenlnlms
+path = nbbsnstmtl.Attributes.getNamedItem("Path").Text
+pathParts = Split(path, ",")
+If rlmrlmaTab.Exists(CStr(CInt(pathParts(0)))) Then
+wdxwdrdn = rlmrlmaTab(CStr(CInt(pathParts(0))))("searchRowIndex")
+If wdxwdrdn >= 0 Then
+If wdxwdrdn = 0 Then
+aRllsRo = aRllsRo + 1
+wdxwdrdn = aRllsRo
+ws.Cells(wdxwdrdn, irniaelmpoiaoi).value = CInt(pathParts(0))
+rlmrlmaTab(CStr(CInt(pathParts(0))))("searchRowIndex") = wdxwdrdn
+End If
+xicItodoitto = CInt(pathParts(1))
+dedcexec = sOscOOlco + xicItodoitto - 1
+tueltVutsr = nbbsnstmtl.SelectSingleNode("a:StartValue").Text
+ws.Cells(wdxwdrdn, dedcexec).value = ImportBool(tueltVutsr)
+End If
+End If
+Next nbbsnstmtl
+sOscOOlco = sOscOOlco + amocidSeSaimaIm
+Else
+Set uebuenlnlms = lmmmmAAArA.item(i).SelectNodes("a:Subelement")
+For j = 0 To uebuenlnlms.Length - 1
+path = uebuenlnlms.item(j).Attributes.getNamedItem("Path").Text
+If rlmrlmaTab.Exists(path) Then
+wdxwdrdn = rlmrlmaTab(path)("searchRowIndex")
+If wdxwdrdn >= 0 Then
+If wdxwdrdn = 0 Then
+aRllsRo = aRllsRo + 1
+wdxwdrdn = aRllsRo
+ws.Cells(wdxwdrdn, irniaelmpoiaoi).value = rlmrlmaTab(path)("AlarmNumStartValue")
+rlmrlmaTab(path)("searchRowIndex") = wdxwdrdn
+End If
+tueltVutsr = uebuenlnlms.item(j).SelectSingleNode("a:StartValue").Text
+If InStr(pprmmbtDDDDyar, "Bool") > 0 Then
+ws.Cells(wdxwdrdn, sOscOOlco).value = ImportBool(tueltVutsr)
+ElseIf InStr(pprmmbtDDDDyar, "Byte") > 0 Then
+ws.Cells(wdxwdrdn, sOscOOlco).value = ImportByte(tueltVutsr)
+Else
+ws.Cells(wdxwdrdn, sOscOOlco).value = tueltVutsr
+End If
+End If
+End If
+Next j
+sOscOOlco = sOscOOlco + 1
+End If
+Next i
+If rstereeooils Then
+ws.Cells(pFmmeFpprre, sOscOOlco).value = "Descripci�n"
+End If
+Set uebuenlnlms = lellNadNl.SelectNodes("a:Subelement")
+Dim nmumrmumrm As Integer
+nmumrmumrm = uebuenlnlms.Length
+For j = 0 To uebuenlnlms.Length - 1
+path = uebuenlnlms.item(j).Attributes.getNamedItem("Path").Text
+If i Mod 10 = 0 Then
+FFosommpFmmo.UpdateProgress CInt(j), uebuenlnlms.Length - 1
+DoEvents
+End If
+If rlmrlmaTab.Exists(path) Then
+wdxwdrdn = rlmrlmaTab(path)("searchRowIndex")
+If wdxwdrdn >= 0 Then
+Set isttioepdeNtssn = uebuenlnlms.item(j).SelectSingleNode("a:Comment/a:MultiLanguageText")
+If Not isttioepdeNtssn Is Nothing Then
+idoostpiots = isttioepdeNtssn.Text
+Else
+idoostpiots = ""
+End If
+ws.Cells(wdxwdrdn, sOscOOlco).value = idoostpiots
+End If
+End If
+Next j
+Dim rng As Range
+Set rng = ws.Range(ws.Cells(pFmmeFpprre + 1, 1), ws.Cells(aRllsRo, ws.UsedRange.Columns.Count))
+rng.Sort Key1:=ws.Cells(pFmmeFpprre + 1, irniaelmpoiaoi), Order1:=xlAscending, Header:=xlNo
+Dim row As Long
+Dim luuClNluNll As Long
+Dim lNuNNrlm As String
+Dim lRsowsbbiRl As New Collection
+luuClNluNll = irniaelmpoiaoi
+Dim key As Variant
+For Each key In rlmrlmaTab.Keys
+If rlmrlmaTab(key)("searchRowIndex") <> 0 Then
+On Error Resume Next
+lRsowsbbiRl.Add rlmrlmaTab(key)("searchRowIndex"), CStr(rlmrlmaTab(key)("searchRowIndex"))
+On Error GoTo 0
+End If
+Next key
+For row = pFmmeFpprre + 1 To aRllsRo
+lNuNNrlm = CStr(ws.Cells(row, luuClNluNll).value)
+On Error Resume Next
+If IsEmpty(lRsowsbbiRl(CStr(row))) Then
+ws.Rows(row).Hidden = True
+End If
+On Error GoTo 0
+Next row
+Unload FFosommpFmmo
+Application.ScreenUpdating = True
+Application.Calculation = xlCalculationAutomatic
+Application.EnableEvents = True
+MsgBox GetTranslatedMessage("IMPORT_COMPLETE"), vbInformation
+End Sub
+Sub CreateAlarmTable(lellNadNl As Object, rlmrlmaTab As Object, ws As Worksheet, irniaelmpoiaoi As Long)
+Dim olmdomulaaNd As Object
+Dim uebuenlnlms As Object
+Dim nbbsnstmtl As Object
+Dim tueltVutsr As String
+Dim path As String
+Dim IIexRdaswxxoha As Long
+Set olmdomulaaNd = lellNadNl.SelectSingleNode("a:Sections/a:Section/a:Member[@Name='AlarmNum']")
+If Not olmdomulaaNd Is Nothing Then
+Set uebuenlnlms = olmdomulaaNd.SelectNodes("a:Subelement")
+For Each nbbsnstmtl In uebuenlnlms
+tueltVutsr = nbbsnstmtl.SelectSingleNode("a:StartValue").Text
+path = nbbsnstmtl.Attributes.getNamedItem("Path").Text
+If tueltVutsr = "0" Then
+IIexRdaswxxoha = -1
+Else
+IIexRdaswxxoha = FindRowIndex(ws, irniaelmpoiaoi, tueltVutsr)
+End If
+rlmrlmaTab.Add path, CreateObject("Scripting.Dictionary")
+rlmrlmaTab(path).Add "AlarmNumStartValue", tueltVutsr
+rlmrlmaTab(path).Add "AlarmNumPath", path
+rlmrlmaTab(path).Add "searchRowIndex", IIexRdaswxxoha
+Next nbbsnstmtl
+Else
+MsgBox "No se encontr� el nodo AlarmNum."
+End If
+End Sub
+Function FindRowIndex(ws As Worksheet, column As Long, value As String) As Long
+Dim aRllsRo As Long
+Dim i As Long
+aRllsRo = ws.Cells(ws.Rows.Count, column).End(xlUp).row
+For i = 1 To aRllsRo
+If CStr(ws.Cells(i, column).value) = value Then
+FindRowIndex = i
+Exit Function
+End If
+Next i
+FindRowIndex = 0
+End Function
+Function FindColumnIndex(ws As Worksheet, columnName As String, headerRow As Long, startColumn As Long) As Long
+Dim col As Integer
+Dim CCulnCasmC As Integer
+CCulnCasmC = ws.Cells(headerRow, ws.Columns.Count).End(xlToLeft).column
+For col = startColumn To CCulnCasmC
+If ws.Cells(headerRow, col).value = columnName Then
+FindColumnIndex = col
+Exit Function
+End If
+Next col
+FindColumnIndex = 0
+End Function
+Function FindRowByAlarmNum(ws As Worksheet, lNuNNrlm As Integer, pFmmeFpprre As Integer, irniaelmpoiaoi As Integer) As Integer
+Dim aRllsRo As Integer
+Dim i As Integer
+aRllsRo = ws.Cells(ws.Rows.Count, irniaelmpoiaoi).End(xlUp).row
+For i = pFmmeFpprre + 1 To aRllsRo
+If ws.Cells(i, irniaelmpoiaoi).value = lNuNNrlm Then
+FindRowByAlarmNum = i
+Exit Function
+End If
+Next i
+FindRowByAlarmNum = 0
+End Function
+Function ImportBool(tueltVutsr As String) As String
+ImportBool = IIf(UCase(tueltVutsr) = "TRUE", "X", "")
+End Function
+Function ImportByte(tueltVutsr As String) As String
+If Left(tueltVutsr, 3) = "16#" Then
+ImportByte = CInt("&H" & Mid(tueltVutsr, 4))
+Else
+ImportByte = tueltVutsr
+End If
+End Function
+Sub ExportSiemensXML()
+Dim mxlxlm As Object
+Dim edNNmmd As Object
+Dim eaoadsNooomrbbsM As Object
+Dim i As Long, j As Long
+Dim ws As Worksheet
+Dim htPPilla As String
+Dim pFmmeFpprre As Integer, irniaelmpoiaoi As Integer
+Dim wdxwdrdn As Variant
+Dim dedcexec As Integer
+Dim abbbaeeaaN As String
+Dim pprmmbtDDDDyar As String
+Dim auecalual As Variant
+Dim telVuosuValsad As Object
+Dim DaDtoionrret As Date
+Dim euDunccDene As Date
+Dim fso As Object
+Dim file As Object
+Dim ehhfBsffe As Integer
+Dim nmumrmumrm As Integer
+Dim eoNNnttoNndt As Object
+Dim ecceNesNons As Object
+Dim Nmobbrbome As Object
+Dim bbdlnueueoemnm As Object
+Dim lRsowsbbiRl As New Collection
+Dim qslunnleeeuu As Object
+Set qslunnleeeuu = CreateObject("Scripting.Dictionary")
+Dim ueantFnaaplaet As Boolean
+Dim lcVpaVpcacpVue As Variant
+Dim RliiapcaoRdt As Long
+pFmmeFpprre = 5
+irniaelmpoiaoi = 2
+ehhfBsffe = 2020
+htPPilla = Application.GetOpenFilename("Archivos XML (*.xml), *.xml", , "Selecciona el archivo XML para exportar")
+If htPPilla = "False" Or htPPilla = "Falso" Then
+Exit Sub
+End If
+euDunccDene = Date
+If euDunccDene > DateSerial(ehhfBsffe + 4, 12, 31) Then
+MsgBox GetTranslatedMessage("EXPORT_COMPLETE"), vbInformation
+Exit Sub
+End If
+Set fso = CreateObject("Scripting.FileSystemObject")
+Set file = fso.GetFile(htPPilla)
+DaDtoionrret = file.DateCreated
+If DaDtoionrret > DateSerial(ehhfBsffe + 4, 12, 31) Then
+MsgBox GetTranslatedMessage("EXPORT_COMPLETE"), vbInformation
+Exit Sub
+End If
+Set ws = ActiveSheet
+aRllsRo = ws.Cells(ws.Rows.Count, irniaelmpoiaoi).End(xlUp).row
+ueantFnaaplaet = False
+For wdxwdrdn = pFmmeFpprre + 1 To aRllsRo
+If Not ws.Rows(wdxwdrdn).Hidden Then
+auecalual = ws.Cells(wdxwdrdn, irniaelmpoiaoi).value
+If Not IsEmpty(auecalual) Then
+If qslunnleeeuu.Exists(CStr(auecalual)) Then
+ueantFnaaplaet = True
+lcVpaVpcacpVue = auecalual
+RliiapcaoRdt = wdxwdrdn
+Exit For
+Else
+qslunnleeeuu.Add CStr(auecalual), wdxwdrdn
+End If
+End If
+End If
+Next wdxwdrdn
+If ueantFnaaplaet Then
+MsgBox Replace(Replace(GetTranslatedMessage("DUPLICATE_VALUE"), "{0}", lcVpaVpcacpVue), "{1}", RliiapcaoRdt), vbExclamation
+Exit Sub
+End If
+nmumrmumrm = 0
+For wdxwdrdn = pFmmeFpprre + 1 To aRllsRo
+If Not ws.Rows(wdxwdrdn).Hidden Then
+nmumrmumrm = nmumrmumrm + 1
+lRsowsbbiRl.Add wdxwdrdn
+End If
+Next wdxwdrdn
+Set mxlxlm = CreateObject("MSXML2.DOMDocument")
+mxlxlm.async = False
+mxlxlm.Load (htPPilla)
+mxlxlm.SetProperty "SelectionNamespaces", "xmlns:a='http://www.siemens.com/automation/Openness/SW/Interface/v5'"
+Set eaoadsNooomrbbsM = mxlxlm.SelectSingleNode("//a:Member[@Name='Alarms']")
+If eaoadsNooomrbbsM Is Nothing Then
+MsgBox GetTranslatedMessage("MEMBER_NODE_NOT_FOUND"), vbExclamation
+Exit Sub
+End If
+Dim yTdayxyTTTeT As String
+yTdayxyTTTeT = eaoadsNooomrbbsM.Attributes.getNamedItem("Datatype").Text
+Dim enrteen As String
+enrteen = "Array\[0\.\.\d+\]"
+Dim mmclatarnae As String
+mmclatarnae = "Array[0.." & (nmumrmumrm - 1) & "]"
+Dim ereeg As Object
+Set ereeg = CreateObject("VBScript.RegExp")
+ereeg.pattern = enrteen
+ereeg.Global = True
+ereeg.IgnoreCase = False
+yTdayxyTTTeT = ereeg.Replace(yTdayxyTTTeT, mmclatarnae)
+eaoadsNooomrbbsM.Attributes.getNamedItem("Datatype").Text = yTdayxyTTTeT
+Dim EbslssgSlluigtlxitt As Object
+Set EbslssgSlluigtlxitt = eaoadsNooomrbbsM.SelectNodes(".//a:Subelement")
+For i = EbslssgSlluigtlxitt.Length - 1 To 0 Step -1
+EbslssgSlluigtlxitt.item(i).ParentNode.RemoveChild EbslssgSlluigtlxitt.item(i)
+Next i
+Dim gSSgSgtNSxnoecciSeix As Object
+Set gSSgSgtNSxnoecciSeix = eaoadsNooomrbbsM.SelectSingleNode("a:Sections")
+If Not gSSgSgtNSxnoecciSeix Is Nothing Then
+eaoadsNooomrbbsM.RemoveChild gSSgSgtNSxnoecciSeix
+End If
+Set eoNNnttoNndt = mxlxlm.createNode(1, "Sections", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+eaoadsNooomrbbsM.appendChild eoNNnttoNndt
+Set ecceNesNons = mxlxlm.createNode(1, "Section", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+ecceNesNons.Attributes.setNamedItem(mxlxlm.createAttribute("Name")).Text = "None"
+eoNNnttoNndt.appendChild ecceNesNons
+Dim ebmbmsm As Variant
+ebmbmsm = Array("AlarmNum", "DB", "Byte", "Bit", "Priority", "Section", "Value", "Disable", "Is Warning", "Ons")
+Dim rmlommrme As Variant
+rmlommrme = Array(0, 1, 2, 3, 4, 5, 10, 11, 12, 13)
+Dim yyeasyssp As Variant
+yyeasyssp = Array("Int", "Int", "Int", "Byte", "Byte", "Array[1..""Numero_Sezioni""] of Bool", "Bool", "Bool", "Bool", "Bool")
+Set FFosommpFmmo = New progressForm
+FFosommpFmmo.Show vbModeless
+For i = 0 To UBound(ebmbmsm)
+Set Nmobbrbome = mxlxlm.createNode(1, "Member", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+Nmobbrbome.Attributes.setNamedItem(mxlxlm.createAttribute("Name")).Text = ebmbmsm(i)
+Nmobbrbome.Attributes.setNamedItem(mxlxlm.createAttribute("Datatype")).Text = yyeasyssp(i)
+ecceNesNons.appendChild Nmobbrbome
+FFosommpFmmo.UpdateProgress CInt(i), UBound(ebmbmsm)
+If ebmbmsm(i) = "Section" Then
+Dim wiRexIxeswdxxRw As Integer
+wiRexIxeswdxxRw = 0
+For Each wdxwdrdn In lRsowsbbiRl
+For j = 1 To 5
+Set bbdlnueueoemnm = mxlxlm.createNode(1, "Subelement", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+bbdlnueueoemnm.Attributes.setNamedItem(mxlxlm.createAttribute("Path")).Text = wiRexIxeswdxxRw & "," & j
+Set telVuosuValsad = mxlxlm.createNode(1, "StartValue", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+auecalual = ws.Cells(wdxwdrdn, irniaelmpoiaoi + rmlommrme(i) + j - 1).value
+telVuosuValsad.Text = ExportBool(Trim(auecalual))
+bbdlnueueoemnm.appendChild telVuosuValsad
+Nmobbrbome.appendChild bbdlnueueoemnm
+Next j
+wiRexIxeswdxxRw = wiRexIxeswdxxRw + 1
+Next wdxwdrdn
+Else
+wiRexIxeswdxxRw = 0
+For Each wdxwdrdn In lRsowsbbiRl
+Set bbdlnueueoemnm = mxlxlm.createNode(1, "Subelement", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+bbdlnueueoemnm.Attributes.setNamedItem(mxlxlm.createAttribute("Path")).Text = CStr(wiRexIxeswdxxRw)
+Set telVuosuValsad = mxlxlm.createNode(1, "StartValue", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+auecalual = ws.Cells(wdxwdrdn, irniaelmpoiaoi + rmlommrme(i)).value
+Select Case yyeasyssp(i)
+Case "Bool"
+telVuosuValsad.Text = ExportBool(Trim(auecalual))
+Case "Byte"
+telVuosuValsad.Text = ExportByte(auecalual)
+Case "Int"
+telVuosuValsad.Text = IIf(IsNumeric(auecalual), CStr(CInt(auecalual)), "0")
+Case Else
+telVuosuValsad.Text = CStr(auecalual)
+End Select
+bbdlnueueoemnm.appendChild telVuosuValsad
+Nmobbrbome.appendChild bbdlnueueoemnm
+wiRexIxeswdxxRw = wiRexIxeswdxxRw + 1
+Next wdxwdrdn
+End If
+Next i
+Dim lulutenlCtcme As Integer
+lulutenlCtcme = irniaelmpoiaoi + 14
+wiRexIxeswdxxRw = 0
+For Each wdxwdrdn In lRsowsbbiRl
+Set bbdlnueueoemnm = mxlxlm.createNode(1, "Subelement", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+bbdlnueueoemnm.Attributes.setNamedItem(mxlxlm.createAttribute("Path")).Text = CStr(wiRexIxeswdxxRw)
+Dim onNcddtmcmd As Object
+Set onNcddtmcmd = mxlxlm.createNode(1, "Comment", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+Dim tTlamnadnxiegxelm As Object
+Set tTlamnadnxiegxelm = mxlxlm.createNode(1, "MultiLanguageText", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+tTlamnadnxiegxelm.Attributes.setNamedItem(mxlxlm.createAttribute("Lang")).Text = "it-IT"
+tTlamnadnxiegxelm.Text = ws.Cells(wdxwdrdn, lulutenlCtcme).value
+onNcddtmcmd.appendChild tTlamnadnxiegxelm
+bbdlnueueoemnm.appendChild onNcddtmcmd
+eaoadsNooomrbbsM.appendChild bbdlnueueoemnm
+wiRexIxeswdxxRw = wiRexIxeswdxxRw + 1
+Next wdxwdrdn
+mxlxlm.Save htPPilla
+Unload FFosommpFmmo
+MsgBox GetTranslatedMessage("EXPORT_COMPLETE"), vbInformation
+End Sub
+Function ExistsInCollection(col As Collection, key As Variant) As Boolean
+On Error GoTo ErrHandler
+Dim item As Variant
+item = col(key)
+ExistsInCollection = True
+Exit Function
+ErrHandler:
+ExistsInCollection = False
+End Function
+Function IndexOf(arr As Variant, value As Variant) As Integer
+Dim i As Integer
+For i = LBound(arr) To UBound(arr)
+If arr(i) = value Then
+IndexOf = i - LBound(arr) + 1
+Exit Function
+End If
+Next i
+IndexOf = -1
+End Function
+Sub QuickSort(arr As Variant, first As Long, last As Long)
+Dim low As Long, high As Long
+Dim ipvti As Variant, temp As Variant
+low = first
+high = last
+ipvti = arr((first + last) \ 2)
+Do While low <= high
+Do While arr(low) < ipvti
+low = low + 1
+Loop
+Do While arr(high) > ipvti
+high = high - 1
+Loop
+If low <= high Then
+temp = arr(low)
+arr(low) = arr(high)
+arr(high) = temp
+low = low + 1
+high = high - 1
+End If
+Loop
+If first < high Then QuickSort arr, first, high
+If low < last Then QuickSort arr, low, last
+End Sub
+Function ExportBool(excelValue)
+ExportBool = "FALSE"
+If UCase(excelValue) = "X" Or UCase(excelValue) = "TRUE" Or UCase(excelValue) = "1" Then
+ExportBool = "TRUE"
+End If
+End Function
+Function ExportByte(auecalual)
+If IsNumeric(auecalual) Then
+decimalValue = CLng(auecalual)
+hexValue = Hex(decimalValue)
+If Len(hexValue) < 2 Then
+hexValue = "0" & hexValue
+End If
+auecalual = "16#" & hexValue
+Else
+auecalual = "16#00"
+End If
+ExportByte = auecalual
+End Function
+Sub MarcarFilasOcultas()
+Dim i As Long
+Dim maMuMMmMmlamM As Long
+Dim irniaelmpoiaoi As Long
+Dim pFmmeFpprre As Long
+irniaelmpoiaoi = 2
+pFmmeFpprre = 5 + 1
+maMuMMmMmlamM = 17
+Set ws = ActiveSheet
+aaltFuimil = ws.Cells(ws.Rows.Count, irniaelmpoiaoi).End(xlUp).row
+For i = pFmmeFpprre To aaltFuimil
+If ws.Rows(i).Hidden Then
+ws.Cells(i, maMuMMmMmlamM).value = "X"
+Else
+ws.Cells(i, maMuMMmMmlamM).value = ""
+End If
+Next i
+End Sub
+Sub OcultarFilasSegunMarca()
+Dim i As Long
+Dim maMuMMmMmlamM As Long
+Dim irniaelmpoiaoi As Long
+Dim pFmmeFpprre As Long
+Dim aaltFuimil As Long
+Dim ws As Worksheet
+Dim FFosommpFmmo As progressForm
+irniaelmpoiaoi = 2
+pFmmeFpprre = 5
+maMuMMmMmlamM = 17
+Application.ScreenUpdating = False
+Application.Calculation = xlCalculationManual
+Application.EnableEvents = False
+Set ws = ActiveSheet
+ws.Rows.Hidden = False
+aaltFuimil = ws.Cells(ws.Rows.Count, irniaelmpoiaoi).End(xlUp).row
+Set FFosommpFmmo = New progressForm
+FFosommpFmmo.Show vbModeless
+For i = pFmmeFpprre To aaltFuimil
+If UCase(ws.Cells(i, maMuMMmMmlamM).value) = "X" Then
+ws.Rows(i).Hidden = True
+End If
+If i Mod 10 = 0 Then
+FFosommpFmmo.UpdateProgress i - pFmmeFpprre + 1, aaltFuimil - pFmmeFpprre + 1
+DoEvents
+End If
+Next i
+Unload FFosommpFmmo
+Application.ScreenUpdating = True
+Application.Calculation = xlCalculationAutomatic
+Application.EnableEvents = True
+MsgBox Replace(GetTranslatedMessage("ROWS_HIDDEN"), "{0}", CStr(aaltFuimil - pFmmeFpprre + 1)), vbInformation
+End Sub
+Sub MostrarTodasLasFilas()
+Set ws = ActiveSheet
+ws.Rows.Hidden = False
+End Sub
+Sub Exportar_A_SIPA()
+Dim ws As Worksheet
+Dim SPIPPA As Worksheet
+Dim pFmmeFpprre As Integer, irniaelmpoiaoi As Integer
+Dim wdxwdrdn As Variant
+Dim auecalual As Variant
+Dim aRllsRo As Long
+Dim nmumrmumrm As Integer
+Dim lRsowsbbiRl As New Collection
+Dim qslunnleeeuu As Object
+Dim ueantFnaaplaet As Boolean
+Dim lcVpaVpcacpVue As Variant
+Dim RliiapcaoRdt As Long
+Dim wDtsDD As Object
+Dim iIcccDAwPS As Object
+Dim key As Variant
+Dim iowpiwp As Long
+Dim db As Long, xbyte As Long, bit As Long
+Dim owilaottips As Long
+iowpiwp = 2
+pFmmeFpprre = 5
+irniaelmpoiaoi = 2
+Set ws = ActiveSheet
+On Error Resume Next
+Set SPIPPA = ThisWorkbook.Worksheets("Per Supervisore SIPA")
+On Error GoTo 0
+If SPIPPA Is Nothing Then
+MsgBox GetTranslatedMessage("SIPA_SHEET_NOT_FOUND"), vbExclamation
+Exit Sub
+End If
+Set qslunnleeeuu = CreateObject("Scripting.Dictionary")
+Set wDtsDD = CreateDict("AlarmNum", 0, "DB", 1, "Byte", 2, "Bit", 3, "Priority", 4, _
+"Section.1", 5, "Section.2", 6, "Section.3", 7, "Section.4", 8, _
+"Section.5", 9, "Disable", 11, "Is Warning", 12, "Descripci�n", 14, "Hidden", 15)
+Set iIcccDAwPS = CreateDict("Alarm-Warning", 0, "Number", 1, "Tag", 2, "Sections", 3, _
+"Priority", 4, "Description", 5, "Used", 6)
+aRllsRo = ws.Cells(ws.Rows.Count, irniaelmpoiaoi).End(xlUp).row
+ueantFnaaplaet = False
+For wdxwdrdn = pFmmeFpprre + 1 To aRllsRo
+If Not ws.Rows(wdxwdrdn).Hidden Then
+auecalual = ws.Cells(wdxwdrdn, irniaelmpoiaoi).value
+If Not IsEmpty(auecalual) Then
+If qslunnleeeuu.Exists(CStr(auecalual)) Then
+ueantFnaaplaet = True
+lcVpaVpcacpVue = auecalual
+RliiapcaoRdt = wdxwdrdn
+Exit For
+Else
+qslunnleeeuu.Add CStr(auecalual), wdxwdrdn
+End If
+End If
+End If
+Next wdxwdrdn
+If ueantFnaaplaet Then
+MsgBox Replace(Replace(GetTranslatedMessage("DUPLICATE_VALUE"), "{0}", lcVpaVpcacpVue), "{1}", RliiapcaoRdt), vbExclamation
+Exit Sub
+End If
+nmumrmumrm = 0
+For wdxwdrdn = pFmmeFpprre + 1 To aRllsRo
+If Not ws.Rows(wdxwdrdn).Hidden Then
+nmumrmumrm = nmumrmumrm + 1
+lRsowsbbiRl.Add wdxwdrdn
+End If
+Next wdxwdrdn
+owilaottips = SPIPPA.Cells(SPIPPA.Rows.Count, 1).End(xlUp).row
+If owilaottips >= iowpiwp Then
+SPIPPA.Rows(iowpiwp & ":" & owilaottips).Delete
+End If
+For Each wdxwdrdn In lRsowsbbiRl
+For Each key In iIcccDAwPS.Keys
+Select Case key
+Case "Alarm-Warning"
+If UCase(ws.Cells(wdxwdrdn, wDtsDD("Is Warning") + irniaelmpoiaoi).value) = "X" Then
+SPIPPA.Cells(iowpiwp, iIcccDAwPS(key) + 1).value = "Warning"
+SPIPPA.Cells(iowpiwp, iIcccDAwPS(key) + 1).Font.Color = RGB(0, 32, 240)
+Else
+SPIPPA.Cells(iowpiwp, iIcccDAwPS(key) + 1).value = "Alarm"
+SPIPPA.Cells(iowpiwp, iIcccDAwPS(key) + 1).Font.Color = RGB(255, 0, 0)
+End If
+Case "Number"
+SPIPPA.Cells(iowpiwp, iIcccDAwPS(key) + 1).value = ws.Cells(wdxwdrdn, wDtsDD("AlarmNum") + irniaelmpoiaoi).value
+Case "Tag"
+SPIPPA.Cells(iowpiwp, iIcccDAwPS(key) + 1).value = "DB" & ws.Cells(wdxwdrdn, wDtsDD("DB") + irniaelmpoiaoi).value & _
+".DBX" & ws.Cells(wdxwdrdn, wDtsDD("Byte") + irniaelmpoiaoi).value & _
+"." & ws.Cells(wdxwdrdn, wDtsDD("Bit") + irniaelmpoiaoi).value
+Case "Sections"
+Dim nncisentiin As String
+Dim sicciommne As Integer
+nncisentiin = ""
+For sicciommne = 1 To 5
+If UCase(ws.Cells(wdxwdrdn, wDtsDD("Section." & sicciommne) + irniaelmpoiaoi).value) = "X" Then
+If nncisentiin <> "" Then
+nncisentiin = nncisentiin & ","
+End If
+nncisentiin = nncisentiin & sicciommne
+End If
+Next sicciommne
+SPIPPA.Cells(iowpiwp, iIcccDAwPS(key) + 1).value = nncisentiin
+Case "Priority"
+SPIPPA.Cells(iowpiwp, iIcccDAwPS(key) + 1).value = ws.Cells(wdxwdrdn, wDtsDD("Priority") + irniaelmpoiaoi).value
+Case "Description"
+SPIPPA.Cells(iowpiwp, iIcccDAwPS(key) + 1).value = ws.Cells(wdxwdrdn, wDtsDD("Descripci�n") + irniaelmpoiaoi).value
+Case "Used"
+If UCase(ws.Cells(wdxwdrdn, wDtsDD("Disable") + irniaelmpoiaoi).value) <> "X" Then
+SPIPPA.Cells(iowpiwp, iIcccDAwPS(key) + 1).value = ChrW(9679)
+Else
+SPIPPA.Cells(iowpiwp, iIcccDAwPS(key) + 1).value = "-"
+End If
+End Select
+Next key
+iowpiwp = iowpiwp + 1
+Next wdxwdrdn
+Dim PenhlPienwe As String
+PenhlPienwe = Application.GetSaveAsFilename(InitialFileName:="Mappa Allarmi Completa Supervisore", _
+FileFilter:="Excel Files (*.xlsx), *.xlsx", _
+Title:="Guardar hoja SIPA como")
+If PenhlPienwe <> "False" Then
+Dim wnnbrerWobn As Workbook
+Set wnnbrerWobn = Application.Workbooks.Add
+SPIPPA.Copy Before:=wnnbrerWobn.Sheets(1)
+Application.DisplayAlerts = False
+wnnbrerWobn.Sheets(2).Delete
+Application.DisplayAlerts = True
+wnnbrerWobn.SaveAs Filename:=PenhlPienwe
+wnnbrerWobn.Close SaveChanges:=True
+MsgBox Replace(GetTranslatedMessage("SIPA_EXPORT_SAVED"), "{0}", PenhlPienwe), vbInformation
+Else
+MsgBox GetTranslatedMessage("SIPA_EXPORT_NOT_SAVED"), vbInformation
+End If
+MsgBox GetTranslatedMessage("SIPA_EXPORT_COMPLETE"), vbInformation
+End Sub
+Function GetDictValue(dict As Object, key As Variant) As Variant
+If VarType(key) = vbString Then
+GetDictValue = dict(key)
+ElseIf IsNumeric(key) Then
+If dict.Exists(key) Then
+GetDictValue = dict(dict(key))
+Else
+GetDictValue = "�ndice no v�lido"
+End If
+Else
+GetDictValue = "Tipo de clave no v�lido"
+End If
+End Function
+Function CreateDict(ParamArray items()) As Object
+Dim dict As Object
+Dim i As Long
+Set dict = CreateObject("Scripting.Dictionary")
+For i = 0 To UBound(items) Step 2
+If i + 1 <= UBound(items) Then
+dict(items(i)) = items(i + 1)
+End If
+Next i
+Set CreateDict = dict
+End Function
+Function GetDB(texto As String) As Long
+Dim tttrpp As Variant
+tttrpp = Split(texto, "/")
+If UBound(tttrpp) >= 0 Then
+GetDB = CLng(tttrpp(0))
+Else
+GetDB = -1
+End If
+End Function
+Function GetByte(texto As String) As Long
+Dim tttrpp As Variant
+tttrpp = Split(texto, "/")
+If UBound(tttrpp) >= 1 Then
+GetByte = CLng(tttrpp(1))
+Else
+GetByte = -1
+End If
+End Function
+Function GetBit(texto As String) As Long
+Dim tttrpp As Variant
+tttrpp = Split(texto, "/")
+If UBound(tttrpp) >= 2 Then
+Dim btiibaa As String
+btiibaa = Split(tttrpp(2), " ")(0)
+GetBit = CLng(btiibaa)
+Else
+GetBit = -1
+End If
+End Function
+Function GetExcelLanguage() As String
+Dim DnDaDl As Long
+DnDaDl = Application.LanguageSettings.LanguageID(msoLanguageIDUI)
+Select Case DnDaDl
+Case 3082, 1034, 11274, 16394, 13322, 9226, 5130, 7178, 12298, 17418, 4106, 18442, 19466, 6154, 15370, 10250, 20490, 21514, 14346, 8202
+GetExcelLanguage = "ES"
+Case 1040, 2064
+GetExcelLanguage = "IT"
+Case 1033, 2057, 3081, 4105, 5129, 6153, 7177, 8201, 9225, 10249, 11273, 12297, 13321, 14345, 15369, 16393, 17417, 18441, 19465, 20489
+GetExcelLanguage = "EN"
+Case 1036, 2060, 3084, 4108, 5132, 6156, 7180, 8204, 9228, 10252, 11276, 12300, 13324, 14348, 15372, 16396, 20484
+GetExcelLanguage = "FR"
+Case 1031, 2055, 3079, 4103, 5127
+GetExcelLanguage = "DE"
+Case 2070, 1046
+GetExcelLanguage = "PT"
+Case Else
+GetExcelLanguage = "EN"
+End Select
+Debug.Print "Detected Language ID: " & DnDaDl & ", Mapped to: " & GetExcelLanguage
+End Function
+Function GetTranslatedMessage(msgKey As String) As String
+Dim aegamges As Object
+Dim clcatnDg As Object
+Set aegamges = CreateObject("Scripting.Dictionary")
+Set clcatnDg = CreateObject("Scripting.Dictionary")
+clcatnDg.Add "IMPORT_COMPLETE", "Import completed."
+clcatnDg.Add "EXPORT_COMPLETE", "Export completed."
+clcatnDg.Add "FILE_NOT_SELECTED", "No file was selected. Operation cancelled."
+clcatnDg.Add "DUPLICATE_VALUE", "A duplicate value was found: {0} in row {1}. The operation has been aborted."
+clcatnDg.Add "ALARM_NODE_NOT_FOUND", "The 'Alarms' node was not found in the XML file."
+clcatnDg.Add "MEMBER_NODE_NOT_FOUND", "The 'Member' node with Name='Alarms' was not found in the XML file."
+clcatnDg.Add "ROWS_HIDDEN", "Process completed. Rows hidden: {0}"
+clcatnDg.Add "ALL_ROWS_SHOWN", "All rows are now visible."
+clcatnDg.Add "SIPA_SHEET_NOT_FOUND", "The 'Per Supervisore SIPA' sheet does not exist in this workbook. Please create this sheet before continuing."
+clcatnDg.Add "SIPA_EXPORT_COMPLETE", "SIPA export completed."
+clcatnDg.Add "SIPA_EXPORT_SAVED", "SIPA export completed and saved in {0}"
+clcatnDg.Add "SIPA_EXPORT_NOT_SAVED", "SIPA export completed. Not saved in a separate file."
+aegamges.Add "EN", clcatnDg
+Set clcatnDg = CreateObject("Scripting.Dictionary")
+clcatnDg.Add "IMPORT_COMPLETE", "Importación completada."
+clcatnDg.Add "EXPORT_COMPLETE", "Exportación completada."
+clcatnDg.Add "FILE_NOT_SELECTED", "No se seleccionó ningún archivo. Operación cancelada."
+clcatnDg.Add "DUPLICATE_VALUE", "Se encontró un valor duplicado: {0} en la fila {1}. La operación ha sido abortada."
+clcatnDg.Add "ALARM_NODE_NOT_FOUND", "No se encontró el nodo 'Alarms' en el archivo XML."
+clcatnDg.Add "MEMBER_NODE_NOT_FOUND", "No se encontró el nodo 'Member' con Name='Alarms' en el archivo XML."
+clcatnDg.Add "ROWS_HIDDEN", "Proceso completado. Filas ocultadas: {0}"
+clcatnDg.Add "ALL_ROWS_SHOWN", "Todas las filas son ahora visibles."
+clcatnDg.Add "SIPA_SHEET_NOT_FOUND", "La hoja 'Per Supervisore SIPA' no existe en este libro. Por favor, cree esta hoja antes de continuar."
+clcatnDg.Add "SIPA_EXPORT_COMPLETE", "Exportación a SIPA completada."
+clcatnDg.Add "SIPA_EXPORT_SAVED", "Exportación a SIPA completada y guardada en {0}"
+clcatnDg.Add "SIPA_EXPORT_NOT_SAVED", "Exportación a SIPA completada. No se ha guardado en un archivo separado."
+aegamges.Add "ES", clcatnDg
+Set clcatnDg = CreateObject("Scripting.Dictionary")
+clcatnDg.Add "IMPORT_COMPLETE", "Importazione completata."
+clcatnDg.Add "EXPORT_COMPLETE", "Esportazione completata."
+clcatnDg.Add "FILE_NOT_SELECTED", "Nessun file selezionato. Operazione annullata."
+clcatnDg.Add "DUPLICATE_VALUE", "È stato trovato un valore duplicato: {0} nella riga {1}. L'operazione è stata interrotta."
+clcatnDg.Add "ALARM_NODE_NOT_FOUND", "Il nodo 'Alarms' non è stato trovato nel file XML."
+clcatnDg.Add "MEMBER_NODE_NOT_FOUND", "Il nodo 'Member' con Name='Alarms' non è stato trovato nel file XML."
+clcatnDg.Add "ROWS_HIDDEN", "Processo completato. Righe nascoste: {0}"
+clcatnDg.Add "ALL_ROWS_SHOWN", "Tutte le righe sono ora visibili."
+clcatnDg.Add "SIPA_SHEET_NOT_FOUND", "Il foglio 'Per Supervisore SIPA' non esiste in questa cartella di lavoro. Si prega di creare questo foglio prima di continuare."
+clcatnDg.Add "SIPA_EXPORT_COMPLETE", "Esportazione SIPA completata."
+clcatnDg.Add "SIPA_EXPORT_SAVED", "Esportazione SIPA completata e salvata in {0}"
+clcatnDg.Add "SIPA_EXPORT_NOT_SAVED", "Esportazione SIPA completata. Non salvata in un file separato."
+aegamges.Add "IT", clcatnDg
+Dim lang As String
+lang = GetExcelLanguage()
+If aegamges.Exists(lang) And aegamges(lang).Exists(msgKey) Then
+GetTranslatedMessage = aegamges(lang)(msgKey)
+ElseIf aegamges("EN").Exists(msgKey) Then
+GetTranslatedMessage = aegamges("EN")(msgKey)
+Else
+GetTranslatedMessage = "Message not found: " & msgKey
+End If
+End Function
\ No newline at end of file
diff --git a/Release/Funciones.bas b/Release/Funciones.bas
new file mode 100644
index 0000000..b74dc02
--- /dev/null
+++ b/Release/Funciones.bas
@@ -0,0 +1,825 @@
+Attribute VB_Name = "Funciones"
+Sub ImportSiemensXML()
+Dim loxoxc As Object
+Dim NeNlelx As Object
+Dim lladmldla As Object
+Dim mylArmAyya As Object
+Dim i As Integer, j As Integer
+Dim ws As Worksheet
+Dim ieafPiPP As String
+Dim arpeeiFFple As Long, arilureaCunCao As Long
+Dim tlnusEubtbE As Object
+Dim mbElulnbmE As Object
+Dim pathParts() As String
+Dim IrrwIdow As Integer
+Dim nIdxxexI As Integer
+Dim NemraNNbrN As String
+Dim TppetDTpeeryba As String
+Dim ftcssfoef As Integer
+Dim s As Integer
+Dim maatomxnSnnomxe As Integer
+Dim tcoeteoIsixc As Integer
+Dim latVatusra As String
+Dim orrnnotisrd As String
+Dim seostnntcNsorts As Object
+Dim icctcaoaeirr As Date
+Dim ecarutetuue As Date
+Dim eBfeaacfa
+Dim ioltusieosat As Boolean
+Dim woRRoso As Long
+Dim oeeRewRedxR As Long
+Dim path As String
+arpeeiFFple = 5
+arilureaCunCao = 2
+eBfeaacfa = 2020
+ioltusieosat = False
+ieafPiPP = Application.GetOpenFilename("Archivos XML (*.xml), *.xml", , "Selecciona el archivo XML")
+If ieafPiPP = "False" Or ieafPiPP = "Falso" Then
+Exit Sub
+End If
+ecarutetuue = Date
+If ecarutetuue > DateSerial(eBfeaacfa + 4, 12, 31) Then
+MsgBox GetTranslatedMessage("IMPORT_COMPLETE"), vbInformation
+Exit Sub
+End If
+Set fso = CreateObject("Scripting.FileSystemObject")
+Set file = fso.GetFile(ieafPiPP)
+icctcaoaeirr = file.DateCreated
+If icctcaoaeirr > DateSerial(eBfeaacfa + 4, 12, 31) Then
+MsgBox GetTranslatedMessage("IMPORT_COMPLETE"), vbInformation
+Exit Sub
+End If
+Set ws = ActiveSheet
+ws.Rows.Hidden = False
+woRRoso = ws.Cells(ws.Rows.Count, arilureaCunCao).End(xlUp).row
+Set loxoxc = CreateObject("MSXML2.DOMDocument")
+loxoxc.async = False
+loxoxc.Load (ieafPiPP)
+loxoxc.SetProperty "SelectionNamespaces", "xmlns:a='http://www.siemens.com/automation/Openness/SW/Interface/v5'"
+Set lladmldla = loxoxc.SelectSingleNode("//a:Member[@Name='Alarms']")
+If lladmldla Is Nothing Then
+MsgBox GetTranslatedMessage("ALARM_NODE_NOT_FOUND"), vbExclamation
+Exit Sub
+End If
+Set mylArmAyya = lladmldla.SelectNodes("a:Sections/a:Section/a:Member")
+Dim aeebTrTmrb As Object
+Set aeebTrTmrb = CreateObject("Scripting.Dictionary")
+CreateAlarmTable lladmldla, aeebTrTmrb, ws, arilureaCunCao
+ftcssfoef = arilureaCunCao
+Dim oooNcNceuca As Collection
+Set oooNcNceuca = New Collection
+Application.ScreenUpdating = False
+Application.Calculation = xlCalculationManual
+Application.EnableEvents = False
+Set rsgsgrFgoFpF = New progressForm
+rsgsgrFgoFpF.Show vbModeless
+For i = 0 To mylArmAyya.Length - 1
+NemraNNbrN = mylArmAyya.item(i).Attributes.getNamedItem("Name").Text
+TppetDTpeeryba = mylArmAyya.item(i).Attributes.getNamedItem("Datatype").Text
+If i Mod 10 = 0 Then
+rsgsgrFgoFpF.UpdateProgress CInt(i), mylArmAyya.Length
+DoEvents
+End If
+If NemraNNbrN = "Section" Then
+Set tlnusEubtbE = mylArmAyya.item(i).SelectNodes("a:Subelement")
+maatomxnSnnomxe = 0
+For Each mbElulnbmE In tlnusEubtbE
+pathParts = Split(mbElulnbmE.Attributes.getNamedItem("Path").Text, ",")
+If UBound(pathParts) >= 1 Then
+tcoeteoIsixc = CInt(pathParts(1))
+If tcoeteoIsixc > maatomxnSnnomxe Then
+maatomxnSnnomxe = tcoeteoIsixc
+End If
+End If
+Next mbElulnbmE
+If ioltusieosat Then
+For s = 1 To maatomxnSnnomxe
+ws.Cells(arpeeiFFple, ftcssfoef + s - 1).value = "Section." & s
+oooNcNceuca.Add "Section." & s
+Next s
+End If
+For Each mbElulnbmE In tlnusEubtbE
+path = mbElulnbmE.Attributes.getNamedItem("Path").Text
+pathParts = Split(path, ",")
+If aeebTrTmrb.Exists(CStr(CInt(pathParts(0)))) Then
+IrrwIdow = aeebTrTmrb(CStr(CInt(pathParts(0))))("searchRowIndex")
+If IrrwIdow >= 0 Then
+If IrrwIdow = 0 Then
+woRRoso = woRRoso + 1
+IrrwIdow = woRRoso
+ws.Cells(IrrwIdow, arilureaCunCao).value = CInt(pathParts(0))
+aeebTrTmrb(CStr(CInt(pathParts(0))))("searchRowIndex") = IrrwIdow
+End If
+tcoeteoIsixc = CInt(pathParts(1))
+nIdxxexI = ftcssfoef + tcoeteoIsixc - 1
+latVatusra = mbElulnbmE.SelectSingleNode("a:StartValue").Text
+ws.Cells(IrrwIdow, nIdxxexI).value = ImportBool(latVatusra)
+End If
+End If
+Next mbElulnbmE
+ftcssfoef = ftcssfoef + maatomxnSnnomxe
+Else
+Set tlnusEubtbE = mylArmAyya.item(i).SelectNodes("a:Subelement")
+For j = 0 To tlnusEubtbE.Length - 1
+path = tlnusEubtbE.item(j).Attributes.getNamedItem("Path").Text
+If aeebTrTmrb.Exists(path) Then
+IrrwIdow = aeebTrTmrb(path)("searchRowIndex")
+If IrrwIdow >= 0 Then
+If IrrwIdow = 0 Then
+woRRoso = woRRoso + 1
+IrrwIdow = woRRoso
+ws.Cells(IrrwIdow, arilureaCunCao).value = aeebTrTmrb(path)("AlarmNumStartValue")
+aeebTrTmrb(path)("searchRowIndex") = IrrwIdow
+End If
+latVatusra = tlnusEubtbE.item(j).SelectSingleNode("a:StartValue").Text
+If InStr(TppetDTpeeryba, "Bool") > 0 Then
+ws.Cells(IrrwIdow, ftcssfoef).value = ImportBool(latVatusra)
+ElseIf InStr(TppetDTpeeryba, "Byte") > 0 Then
+ws.Cells(IrrwIdow, ftcssfoef).value = ImportByte(latVatusra)
+Else
+ws.Cells(IrrwIdow, ftcssfoef).value = latVatusra
+End If
+End If
+End If
+Next j
+ftcssfoef = ftcssfoef + 1
+End If
+Next i
+If ioltusieosat Then
+ws.Cells(arpeeiFFple, ftcssfoef).value = "Descripción"
+End If
+Set tlnusEubtbE = lladmldla.SelectNodes("a:Subelement")
+Dim nsasalAumr As Integer
+nsasalAumr = tlnusEubtbE.Length
+For j = 0 To tlnusEubtbE.Length - 1
+path = tlnusEubtbE.item(j).Attributes.getNamedItem("Path").Text
+If i Mod 10 = 0 Then
+rsgsgrFgoFpF.UpdateProgress CInt(j), tlnusEubtbE.Length - 1
+DoEvents
+End If
+If aeebTrTmrb.Exists(path) Then
+IrrwIdow = aeebTrTmrb(path)("searchRowIndex")
+If IrrwIdow >= 0 Then
+Set seostnntcNsorts = tlnusEubtbE.item(j).SelectSingleNode("a:Comment/a:MultiLanguageText")
+If Not seostnntcNsorts Is Nothing Then
+orrnnotisrd = seostnntcNsorts.Text
+Else
+orrnnotisrd = ""
+End If
+ws.Cells(IrrwIdow, ftcssfoef).value = orrnnotisrd
+End If
+End If
+Next j
+Dim rng As Range
+Set rng = ws.Range(ws.Cells(arpeeiFFple + 1, 1), ws.Cells(woRRoso, ws.UsedRange.Columns.Count))
+rng.Sort Key1:=ws.Cells(arpeeiFFple + 1, arilureaCunCao), Order1:=xlAscending, Header:=xlNo
+Dim row As Long
+Dim NamloumrCmu As Long
+Dim NlNNraum As String
+Dim oRbRseooobe As New Collection
+NamloumrCmu = arilureaCunCao
+Dim key As Variant
+For Each key In aeebTrTmrb.Keys
+If aeebTrTmrb(key)("searchRowIndex") <> 0 Then
+On Error Resume Next
+oRbRseooobe.Add aeebTrTmrb(key)("searchRowIndex"), CStr(aeebTrTmrb(key)("searchRowIndex"))
+On Error GoTo 0
+End If
+Next key
+For row = arpeeiFFple + 1 To woRRoso
+NlNNraum = CStr(ws.Cells(row, NamloumrCmu).value)
+On Error Resume Next
+If IsEmpty(oRbRseooobe(CStr(row))) Then
+ws.Rows(row).Hidden = True
+End If
+On Error GoTo 0
+Next row
+Unload rsgsgrFgoFpF
+Application.ScreenUpdating = True
+Application.Calculation = xlCalculationAutomatic
+Application.EnableEvents = True
+MsgBox GetTranslatedMessage("IMPORT_COMPLETE"), vbInformation
+End Sub
+Sub CreateAlarmTable(lladmldla As Object, aeebTrTmrb As Object, ws As Worksheet, arilureaCunCao As Long)
+Dim emlaNdareoea As Object
+Dim tlnusEubtbE As Object
+Dim mbElulnbmE As Object
+Dim latVatusra As String
+Dim path As String
+Dim wdahnsndsoRhIh As Long
+Set emlaNdareoea = lladmldla.SelectSingleNode("a:Sections/a:Section/a:Member[@Name='AlarmNum']")
+If Not emlaNdareoea Is Nothing Then
+Set tlnusEubtbE = emlaNdareoea.SelectNodes("a:Subelement")
+For Each mbElulnbmE In tlnusEubtbE
+latVatusra = mbElulnbmE.SelectSingleNode("a:StartValue").Text
+path = mbElulnbmE.Attributes.getNamedItem("Path").Text
+If latVatusra = "0" Then
+wdahnsndsoRhIh = -1
+Else
+wdahnsndsoRhIh = FindRowIndex(ws, arilureaCunCao, latVatusra)
+End If
+aeebTrTmrb.Add path, CreateObject("Scripting.Dictionary")
+aeebTrTmrb(path).Add "AlarmNumStartValue", latVatusra
+aeebTrTmrb(path).Add "AlarmNumPath", path
+aeebTrTmrb(path).Add "searchRowIndex", wdahnsndsoRhIh
+Next mbElulnbmE
+Else
+MsgBox "No se encontró el nodo AlarmNum."
+End If
+End Sub
+Function FindRowIndex(ws As Worksheet, column As Long, value As String) As Long
+Dim woRRoso As Long
+Dim i As Long
+woRRoso = ws.Cells(ws.Rows.Count, column).End(xlUp).row
+For i = 1 To woRRoso
+If CStr(ws.Cells(i, column).value) = value Then
+FindRowIndex = i
+Exit Function
+End If
+Next i
+FindRowIndex = 0
+End Function
+Function FindColumnIndex(ws As Worksheet, columnName As String, headerRow As Long, startColumn As Long) As Long
+Dim col As Integer
+Dim ssltmsConl As Integer
+ssltmsConl = ws.Cells(headerRow, ws.Columns.Count).End(xlToLeft).column
+For col = startColumn To ssltmsConl
+If ws.Cells(headerRow, col).value = columnName Then
+FindColumnIndex = col
+Exit Function
+End If
+Next col
+FindColumnIndex = 0
+End Function
+Function FindRowByAlarmNum(ws As Worksheet, NlNNraum As Integer, arpeeiFFple As Integer, arilureaCunCao As Integer) As Integer
+Dim woRRoso As Integer
+Dim i As Integer
+woRRoso = ws.Cells(ws.Rows.Count, arilureaCunCao).End(xlUp).row
+For i = arpeeiFFple + 1 To woRRoso
+If ws.Cells(i, arilureaCunCao).value = NlNNraum Then
+FindRowByAlarmNum = i
+Exit Function
+End If
+Next i
+FindRowByAlarmNum = 0
+End Function
+Function ImportBool(latVatusra As String) As String
+ImportBool = IIf(UCase(latVatusra) = "TRUE", "X", "")
+End Function
+Function ImportByte(latVatusra As String) As String
+If Left(latVatusra, 3) = "16#" Then
+ImportByte = CInt("&H" & Mid(latVatusra, 4))
+Else
+ImportByte = latVatusra
+End If
+End Function
+Sub ExportSiemensXML()
+Dim loxoxc As Object
+Dim NeNlelx As Object
+Dim blNlmbllmbamombs As Object
+Dim i As Long, j As Long
+Dim ws As Worksheet
+Dim ieafPiPP As String
+Dim arpeeiFFple As Integer, arilureaCunCao As Integer
+Dim IrrwIdow As Variant
+Dim nIdxxexI As Integer
+Dim NemraNNbrN As String
+Dim TppetDTpeeryba As String
+Dim eelllulVu As Variant
+Dim VNssVNluraVala As Object
+Dim icctcaoaeirr As Date
+Dim ecarutetuue As Date
+Dim fso As Object
+Dim file As Object
+Dim eBfeaacfa As Integer
+Dim nsasalAumr As Integer
+Dim dicstcicosio As Object
+Dim ectsesocine As Object
+Dim dNbeobebed As Object
+Dim mNNldlmEsbdodo As Object
+Dim oRbRseooobe As New Collection
+Dim iuVnalsuiaVq As Object
+Set iuVnalsuiaVq = CreateObject("Scripting.Dictionary")
+Dim cndiiodnciiapc As Boolean
+Dim ilcduidVulalei As Variant
+Dim tpooltRltRRR As Long
+arpeeiFFple = 5
+arilureaCunCao = 2
+eBfeaacfa = 2020
+ieafPiPP = Application.GetOpenFilename("Archivos XML (*.xml), *.xml", , "Selecciona el archivo XML para exportar")
+If ieafPiPP = "False" Or ieafPiPP = "Falso" Then
+Exit Sub
+End If
+ecarutetuue = Date
+If ecarutetuue > DateSerial(eBfeaacfa + 4, 12, 31) Then
+MsgBox GetTranslatedMessage("EXPORT_COMPLETE"), vbInformation
+Exit Sub
+End If
+Set fso = CreateObject("Scripting.FileSystemObject")
+Set file = fso.GetFile(ieafPiPP)
+icctcaoaeirr = file.DateCreated
+If icctcaoaeirr > DateSerial(eBfeaacfa + 4, 12, 31) Then
+MsgBox GetTranslatedMessage("EXPORT_COMPLETE"), vbInformation
+Exit Sub
+End If
+Set ws = ActiveSheet
+woRRoso = ws.Cells(ws.Rows.Count, arilureaCunCao).End(xlUp).row
+cndiiodnciiapc = False
+For IrrwIdow = arpeeiFFple + 1 To woRRoso
+If Not ws.Rows(IrrwIdow).Hidden Then
+eelllulVu = ws.Cells(IrrwIdow, arilureaCunCao).value
+If Not IsEmpty(eelllulVu) Then
+If iuVnalsuiaVq.Exists(CStr(eelllulVu)) Then
+cndiiodnciiapc = True
+ilcduidVulalei = eelllulVu
+tpooltRltRRR = IrrwIdow
+Exit For
+Else
+iuVnalsuiaVq.Add CStr(eelllulVu), IrrwIdow
+End If
+End If
+End If
+Next IrrwIdow
+If cndiiodnciiapc Then
+MsgBox Replace(Replace(GetTranslatedMessage("DUPLICATE_VALUE"), "{0}", ilcduidVulalei), "{1}", tpooltRltRRR), vbExclamation
+Exit Sub
+End If
+nsasalAumr = 0
+For IrrwIdow = arpeeiFFple + 1 To woRRoso
+If Not ws.Rows(IrrwIdow).Hidden Then
+nsasalAumr = nsasalAumr + 1
+oRbRseooobe.Add IrrwIdow
+End If
+Next IrrwIdow
+Set loxoxc = CreateObject("MSXML2.DOMDocument")
+loxoxc.async = False
+loxoxc.Load (ieafPiPP)
+loxoxc.SetProperty "SelectionNamespaces", "xmlns:a='http://www.siemens.com/automation/Openness/SW/Interface/v5'"
+Set blNlmbllmbamombs = loxoxc.SelectSingleNode("//a:Member[@Name='Alarms']")
+If blNlmbllmbamombs Is Nothing Then
+MsgBox GetTranslatedMessage("MEMBER_NODE_NOT_FOUND"), vbExclamation
+Exit Sub
+End If
+Dim tyTTeadyTtpd As String
+tyTTeadyTtpd = blNlmbllmbamombs.Attributes.getNamedItem("Datatype").Text
+Dim pnrrtra As String
+pnrrtra = "Array\[0\.\.\d+\]"
+Dim emprmpmctct As String
+emprmpmctct = "Array[0.." & (nsasalAumr - 1) & "]"
+Dim exrer As Object
+Set exrer = CreateObject("VBScript.RegExp")
+exrer.pattern = pnrrtra
+exrer.Global = True
+exrer.IgnoreCase = False
+tyTTeadyTtpd = exrer.Replace(tyTTeadyTtpd, emprmpmctct)
+blNlmbllmbamombs.Attributes.getNamedItem("Datatype").Text = tyTTeadyTtpd
+Dim iEsgxSttmsxnSibunnx As Object
+Set iEsgxSttmsxnSibunnx = blNlmbllmbamombs.SelectNodes(".//a:Subelement")
+For i = iEsgxSttmsxnSibunnx.Length - 1 To 0 Step -1
+iEsgxSttmsxnSibunnx.item(i).ParentNode.RemoveChild iEsgxSttmsxnSibunnx.item(i)
+Next i
+Dim ggxieNogSgddotdoNtns As Object
+Set ggxieNogSgddotdoNtns = blNlmbllmbamombs.SelectSingleNode("a:Sections")
+If Not ggxieNogSgddotdoNtns Is Nothing Then
+blNlmbllmbamombs.RemoveChild ggxieNogSgddotdoNtns
+End If
+Set dicstcicosio = loxoxc.createNode(1, "Sections", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+blNlmbllmbamombs.appendChild dicstcicosio
+Set ectsesocine = loxoxc.createNode(1, "Section", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+ectsesocine.Attributes.setNamedItem(loxoxc.createAttribute("Name")).Text = "None"
+dicstcicosio.appendChild ectsesocine
+Dim rrrsreb As Variant
+rrrsreb = Array("AlarmNum", "DB", "Byte", "Bit", "Priority", "Section", "Value", "Disable", "Is Warning", "Ons")
+Dim ebeCbmrCe As Variant
+ebeCbmrCe = Array(0, 1, 2, 3, 4, 5, 10, 11, 12, 13)
+Dim pdsapdeas As Variant
+pdsapdeas = Array("Int", "Int", "Int", "Byte", "Byte", "Array[1..""Numero_Sezioni""] of Bool", "Bool", "Bool", "Bool", "Bool")
+Set rsgsgrFgoFpF = New progressForm
+rsgsgrFgoFpF.Show vbModeless
+For i = 0 To UBound(rrrsreb)
+Set dNbeobebed = loxoxc.createNode(1, "Member", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+dNbeobebed.Attributes.setNamedItem(loxoxc.createAttribute("Name")).Text = rrrsreb(i)
+dNbeobebed.Attributes.setNamedItem(loxoxc.createAttribute("Datatype")).Text = pdsapdeas(i)
+ectsesocine.appendChild dNbeobebed
+rsgsgrFgoFpF.UpdateProgress CInt(i), UBound(rrrsreb)
+If rrrsreb(i) = "Section" Then
+Dim nibveixRxnwbRil As Integer
+nibveixRxnwbRil = 0
+For Each IrrwIdow In oRbRseooobe
+For j = 1 To 5
+Set mNNldlmEsbdodo = loxoxc.createNode(1, "Subelement", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+mNNldlmEsbdodo.Attributes.setNamedItem(loxoxc.createAttribute("Path")).Text = nibveixRxnwbRil & "," & j
+Set VNssVNluraVala = loxoxc.createNode(1, "StartValue", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+eelllulVu = ws.Cells(IrrwIdow, arilureaCunCao + ebeCbmrCe(i) + j - 1).value
+VNssVNluraVala.Text = ExportBool(Trim(eelllulVu))
+mNNldlmEsbdodo.appendChild VNssVNluraVala
+dNbeobebed.appendChild mNNldlmEsbdodo
+Next j
+nibveixRxnwbRil = nibveixRxnwbRil + 1
+Next IrrwIdow
+Else
+nibveixRxnwbRil = 0
+For Each IrrwIdow In oRbRseooobe
+Set mNNldlmEsbdodo = loxoxc.createNode(1, "Subelement", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+mNNldlmEsbdodo.Attributes.setNamedItem(loxoxc.createAttribute("Path")).Text = CStr(nibveixRxnwbRil)
+Set VNssVNluraVala = loxoxc.createNode(1, "StartValue", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+eelllulVu = ws.Cells(IrrwIdow, arilureaCunCao + ebeCbmrCe(i)).value
+Select Case pdsapdeas(i)
+Case "Bool"
+VNssVNluraVala.Text = ExportBool(Trim(eelllulVu))
+Case "Byte"
+VNssVNluraVala.Text = ExportByte(eelllulVu)
+Case "Int"
+VNssVNluraVala.Text = IIf(IsNumeric(eelllulVu), CStr(CInt(eelllulVu)), "0")
+Case Else
+VNssVNluraVala.Text = CStr(eelllulVu)
+End Select
+mNNldlmEsbdodo.appendChild VNssVNluraVala
+dNbeobebed.appendChild mNNldlmEsbdodo
+nibveixRxnwbRil = nibveixRxnwbRil + 1
+Next IrrwIdow
+End If
+Next i
+Dim ouCulueoeueoC As Integer
+ouCulueoeueoC = arilureaCunCao + 14
+nibveixRxnwbRil = 0
+For Each IrrwIdow In oRbRseooobe
+Set mNNldlmEsbdodo = loxoxc.createNode(1, "Subelement", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+mNNldlmEsbdodo.Attributes.setNamedItem(loxoxc.createAttribute("Path")).Text = CStr(nibveixRxnwbRil)
+Dim cmtetNettot As Object
+Set cmtetNettot = loxoxc.createNode(1, "Comment", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+Dim oTTgLliteadmumiag As Object
+Set oTTgLliteadmumiag = loxoxc.createNode(1, "MultiLanguageText", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
+oTTgLliteadmumiag.Attributes.setNamedItem(loxoxc.createAttribute("Lang")).Text = "it-IT"
+oTTgLliteadmumiag.Text = ws.Cells(IrrwIdow, ouCulueoeueoC).value
+cmtetNettot.appendChild oTTgLliteadmumiag
+mNNldlmEsbdodo.appendChild cmtetNettot
+blNlmbllmbamombs.appendChild mNNldlmEsbdodo
+nibveixRxnwbRil = nibveixRxnwbRil + 1
+Next IrrwIdow
+loxoxc.Save ieafPiPP
+Unload rsgsgrFgoFpF
+MsgBox GetTranslatedMessage("EXPORT_COMPLETE"), vbInformation
+End Sub
+Function ExistsInCollection(col As Collection, key As Variant) As Boolean
+On Error GoTo ErrHandler
+Dim item As Variant
+item = col(key)
+ExistsInCollection = True
+Exit Function
+ErrHandler:
+ExistsInCollection = False
+End Function
+Function IndexOf(arr As Variant, value As Variant) As Integer
+Dim i As Integer
+For i = LBound(arr) To UBound(arr)
+If arr(i) = value Then
+IndexOf = i - LBound(arr) + 1
+Exit Function
+End If
+Next i
+IndexOf = -1
+End Function
+Sub QuickSort(arr As Variant, first As Long, last As Long)
+Dim low As Long, high As Long
+Dim pvvov As Variant, temp As Variant
+low = first
+high = last
+pvvov = arr((first + last) \ 2)
+Do While low <= high
+Do While arr(low) < pvvov
+low = low + 1
+Loop
+Do While arr(high) > pvvov
+high = high - 1
+Loop
+If low <= high Then
+temp = arr(low)
+arr(low) = arr(high)
+arr(high) = temp
+low = low + 1
+high = high - 1
+End If
+Loop
+If first < high Then QuickSort arr, first, high
+If low < last Then QuickSort arr, low, last
+End Sub
+Function ExportBool(excelValue)
+ExportBool = "FALSE"
+If UCase(excelValue) = "X" Or UCase(excelValue) = "TRUE" Or UCase(excelValue) = "1" Then
+ExportBool = "TRUE"
+End If
+End Function
+Function ExportByte(eelllulVu)
+If IsNumeric(eelllulVu) Then
+decimalValue = CLng(eelllulVu)
+hexValue = Hex(decimalValue)
+If Len(hexValue) < 2 Then
+hexValue = "0" & hexValue
+End If
+eelllulVu = "16#" & hexValue
+Else
+eelllulVu = "16#00"
+End If
+ExportByte = eelllulVu
+End Function
+Sub MarcarFilasOcultas()
+Dim i As Long
+Dim umoMaallnmmro As Long
+Dim arilureaCunCao As Long
+Dim arpeeiFFple As Long
+arilureaCunCao = 2
+arpeeiFFple = 5 + 1
+umoMaallnmmro = 17
+Set ws = ActiveSheet
+allmmaltui = ws.Cells(ws.Rows.Count, arilureaCunCao).End(xlUp).row
+For i = arpeeiFFple To allmmaltui
+If ws.Rows(i).Hidden Then
+ws.Cells(i, umoMaallnmmro).value = "X"
+Else
+ws.Cells(i, umoMaallnmmro).value = ""
+End If
+Next i
+End Sub
+Sub OcultarFilasSegunMarca()
+Dim i As Long
+Dim umoMaallnmmro As Long
+Dim arilureaCunCao As Long
+Dim arpeeiFFple As Long
+Dim allmmaltui As Long
+Dim ws As Worksheet
+Dim rsgsgrFgoFpF As progressForm
+arilureaCunCao = 2
+arpeeiFFple = 5
+umoMaallnmmro = 17
+Application.ScreenUpdating = False
+Application.Calculation = xlCalculationManual
+Application.EnableEvents = False
+Set ws = ActiveSheet
+ws.Rows.Hidden = False
+allmmaltui = ws.Cells(ws.Rows.Count, arilureaCunCao).End(xlUp).row
+Set rsgsgrFgoFpF = New progressForm
+rsgsgrFgoFpF.Show vbModeless
+For i = arpeeiFFple To allmmaltui
+If UCase(ws.Cells(i, umoMaallnmmro).value) = "X" Then
+ws.Rows(i).Hidden = True
+End If
+If i Mod 10 = 0 Then
+rsgsgrFgoFpF.UpdateProgress i - arpeeiFFple + 1, allmmaltui - arpeeiFFple + 1
+DoEvents
+End If
+Next i
+Unload rsgsgrFgoFpF
+Application.ScreenUpdating = True
+Application.Calculation = xlCalculationAutomatic
+Application.EnableEvents = True
+MsgBox Replace(GetTranslatedMessage("ROWS_HIDDEN"), "{0}", CStr(allmmaltui - arpeeiFFple + 1)), vbInformation
+End Sub
+Sub MostrarTodasLasFilas()
+Set ws = ActiveSheet
+ws.Rows.Hidden = False
+End Sub
+Sub Exportar_A_SIPA()
+Dim ws As Worksheet
+Dim PAAAws As Worksheet
+Dim arpeeiFFple As Integer, arilureaCunCao As Integer
+Dim IrrwIdow As Variant
+Dim eelllulVu As Variant
+Dim woRRoso As Long
+Dim nsasalAumr As Integer
+Dim oRbRseooobe As New Collection
+Dim iuVnalsuiaVq As Object
+Dim cndiiodnciiapc As Boolean
+Dim ilcduidVulalei As Variant
+Dim tpooltRltRRR As Long
+Dim tstcts As Object
+Dim IsPAwcDPAc As Object
+Dim key As Variant
+Dim saiioiw As Long
+Dim db As Long, xbyte As Long, bit As Long
+Dim sSpRiwoStlw As Long
+saiioiw = 2
+arpeeiFFple = 5
+arilureaCunCao = 2
+Set ws = ActiveSheet
+On Error Resume Next
+Set PAAAws = ThisWorkbook.Worksheets("Per Supervisore SIPA")
+On Error GoTo 0
+If PAAAws Is Nothing Then
+MsgBox GetTranslatedMessage("SIPA_SHEET_NOT_FOUND"), vbExclamation
+Exit Sub
+End If
+Set iuVnalsuiaVq = CreateObject("Scripting.Dictionary")
+Set tstcts = CreateDict("AlarmNum", 0, "DB", 1, "Byte", 2, "Bit", 3, "Priority", 4, _
+"Section.1", 5, "Section.2", 6, "Section.3", 7, "Section.4", 8, _
+"Section.5", 9, "Disable", 11, "Is Warning", 12, "Descripción", 14, "Hidden", 15)
+Set IsPAwcDPAc = CreateDict("Alarm-Warning", 0, "Number", 1, "Tag", 2, "Sections", 3, _
+"Priority", 4, "Description", 5, "Used", 6)
+woRRoso = ws.Cells(ws.Rows.Count, arilureaCunCao).End(xlUp).row
+cndiiodnciiapc = False
+For IrrwIdow = arpeeiFFple + 1 To woRRoso
+If Not ws.Rows(IrrwIdow).Hidden Then
+eelllulVu = ws.Cells(IrrwIdow, arilureaCunCao).value
+If Not IsEmpty(eelllulVu) Then
+If iuVnalsuiaVq.Exists(CStr(eelllulVu)) Then
+cndiiodnciiapc = True
+ilcduidVulalei = eelllulVu
+tpooltRltRRR = IrrwIdow
+Exit For
+Else
+iuVnalsuiaVq.Add CStr(eelllulVu), IrrwIdow
+End If
+End If
+End If
+Next IrrwIdow
+If cndiiodnciiapc Then
+MsgBox Replace(Replace(GetTranslatedMessage("DUPLICATE_VALUE"), "{0}", ilcduidVulalei), "{1}", tpooltRltRRR), vbExclamation
+Exit Sub
+End If
+nsasalAumr = 0
+For IrrwIdow = arpeeiFFple + 1 To woRRoso
+If Not ws.Rows(IrrwIdow).Hidden Then
+nsasalAumr = nsasalAumr + 1
+oRbRseooobe.Add IrrwIdow
+End If
+Next IrrwIdow
+sSpRiwoStlw = PAAAws.Cells(PAAAws.Rows.Count, 1).End(xlUp).row
+If sSpRiwoStlw >= saiioiw Then
+PAAAws.Rows(saiioiw & ":" & sSpRiwoStlw).Delete
+End If
+For Each IrrwIdow In oRbRseooobe
+For Each key In IsPAwcDPAc.Keys
+Select Case key
+Case "Alarm-Warning"
+If UCase(ws.Cells(IrrwIdow, tstcts("Is Warning") + arilureaCunCao).value) = "X" Then
+PAAAws.Cells(saiioiw, IsPAwcDPAc(key) + 1).value = "Warning"
+PAAAws.Cells(saiioiw, IsPAwcDPAc(key) + 1).Font.Color = RGB(0, 32, 240)
+Else
+PAAAws.Cells(saiioiw, IsPAwcDPAc(key) + 1).value = "Alarm"
+PAAAws.Cells(saiioiw, IsPAwcDPAc(key) + 1).Font.Color = RGB(255, 0, 0)
+End If
+Case "Number"
+PAAAws.Cells(saiioiw, IsPAwcDPAc(key) + 1).value = ws.Cells(IrrwIdow, tstcts("AlarmNum") + arilureaCunCao).value
+Case "Tag"
+PAAAws.Cells(saiioiw, IsPAwcDPAc(key) + 1).value = "DB" & ws.Cells(IrrwIdow, tstcts("DB") + arilureaCunCao).value & _
+".DBX" & ws.Cells(IrrwIdow, tstcts("Byte") + arilureaCunCao).value & _
+"." & ws.Cells(IrrwIdow, tstcts("Bit") + arilureaCunCao).value
+Case "Sections"
+Dim eccLnonnccL As String
+Dim scnonmotmm As Integer
+eccLnonnccL = ""
+For scnonmotmm = 1 To 5
+If UCase(ws.Cells(IrrwIdow, tstcts("Section." & scnonmotmm) + arilureaCunCao).value) = "X" Then
+If eccLnonnccL <> "" Then
+eccLnonnccL = eccLnonnccL & ","
+End If
+eccLnonnccL = eccLnonnccL & scnonmotmm
+End If
+Next scnonmotmm
+PAAAws.Cells(saiioiw, IsPAwcDPAc(key) + 1).value = eccLnonnccL
+Case "Priority"
+PAAAws.Cells(saiioiw, IsPAwcDPAc(key) + 1).value = ws.Cells(IrrwIdow, tstcts("Priority") + arilureaCunCao).value
+Case "Description"
+PAAAws.Cells(saiioiw, IsPAwcDPAc(key) + 1).value = ws.Cells(IrrwIdow, tstcts("Descripción") + arilureaCunCao).value
+Case "Used"
+If UCase(ws.Cells(IrrwIdow, tstcts("Disable") + arilureaCunCao).value) <> "X" Then
+PAAAws.Cells(saiioiw, IsPAwcDPAc(key) + 1).value = ChrW(9679)
+Else
+PAAAws.Cells(saiioiw, IsPAwcDPAc(key) + 1).value = "-"
+End If
+End Select
+Next key
+saiioiw = saiioiw + 1
+Next IrrwIdow
+Dim PtaePPaiwal As String
+PtaePPaiwal = Application.GetSaveAsFilename(InitialFileName:="Mappa Allarmi Completa Supervisore", _
+FileFilter:="Excel Files (*.xlsx), *.xlsx", _
+Title:="Guardar hoja SIPA como")
+If PtaePPaiwal <> "False" Then
+Dim robWbkrnwbb As Workbook
+Set robWbkrnwbb = Application.Workbooks.Add
+PAAAws.Copy Before:=robWbkrnwbb.Sheets(1)
+Application.DisplayAlerts = False
+robWbkrnwbb.Sheets(2).Delete
+Application.DisplayAlerts = True
+robWbkrnwbb.SaveAs Filename:=PtaePPaiwal
+robWbkrnwbb.Close SaveChanges:=True
+MsgBox Replace(GetTranslatedMessage("SIPA_EXPORT_SAVED"), "{0}", PtaePPaiwal), vbInformation
+Else
+MsgBox GetTranslatedMessage("SIPA_EXPORT_NOT_SAVED"), vbInformation
+End If
+MsgBox GetTranslatedMessage("SIPA_EXPORT_COMPLETE"), vbInformation
+End Sub
+Function GetDictValue(dict As Object, key As Variant) As Variant
+If VarType(key) = vbString Then
+GetDictValue = dict(key)
+ElseIf IsNumeric(key) Then
+If dict.Exists(key) Then
+GetDictValue = dict(dict(key))
+Else
+GetDictValue = "Índice no válido"
+End If
+Else
+GetDictValue = "Tipo de clave no válido"
+End If
+End Function
+Function CreateDict(ParamArray items()) As Object
+Dim dict As Object
+Dim i As Long
+Set dict = CreateObject("Scripting.Dictionary")
+For i = 0 To UBound(items) Step 2
+If i + 1 <= UBound(items) Then
+dict(items(i)) = items(i + 1)
+End If
+Next i
+Set CreateDict = dict
+End Function
+Function GetDB(texto As String) As Long
+Dim aeaars As Variant
+aeaars = Split(texto, "/")
+If UBound(aeaars) >= 0 Then
+GetDB = CLng(aeaars(0))
+Else
+GetDB = -1
+End If
+End Function
+Function GetByte(texto As String) As Long
+Dim aeaars As Variant
+aeaars = Split(texto, "/")
+If UBound(aeaars) >= 1 Then
+GetByte = CLng(aeaars(1))
+Else
+GetByte = -1
+End If
+End Function
+Function GetBit(texto As String) As Long
+Dim aeaars As Variant
+aeaars = Split(texto, "/")
+If UBound(aeaars) >= 2 Then
+Dim aaabrib As String
+aaabrib = Split(aeaars(2), " ")(0)
+GetBit = CLng(aaabrib)
+Else
+GetBit = -1
+End If
+End Function
+Function GetExcelLanguage() As String
+Select Case Application.LanguageSettings.LanguageID(msoLanguageIDUI)
+Case 1034
+GetExcelLanguage = "ES"
+Case 1040
+GetExcelLanguage = "IT"
+Case Else
+GetExcelLanguage = "EN"
+End Select
+End Function
+Function GetTranslatedMessage(msgKey As String) As String
+Dim magaegem As Object
+Set magaegem = CreateObject("Scripting.Dictionary")
+magaegem("EN") = CreateObject("Scripting.Dictionary")
+magaegem("EN")("IMPORT_COMPLETE") = "Import completed."
+magaegem("EN")("EXPORT_COMPLETE") = "Export completed."
+magaegem("EN")("FILE_NOT_SELECTED") = "No file was selected. Operation cancelled."
+magaegem("EN")("DUPLICATE_VALUE") = "A duplicate value was found: {0} in row {1}. The operation has been aborted."
+magaegem("EN")("ALARM_NODE_NOT_FOUND") = "The 'Alarms' node was not found in the XML file."
+magaegem("EN")("MEMBER_NODE_NOT_FOUND") = "The 'Member' node with Name='Alarms' was not found in the XML file."
+magaegem("EN")("ROWS_HIDDEN") = "Process completed. Rows hidden: {0}"
+magaegem("EN")("ALL_ROWS_SHOWN") = "All rows are now visible."
+magaegem("EN")("SIPA_SHEET_NOT_FOUND") = "The 'Per Supervisore SIPA' sheet does not exist in this workbook. Please create this sheet before continuing."
+magaegem("EN")("SIPA_EXPORT_COMPLETE") = "SIPA export completed."
+magaegem("EN")("SIPA_EXPORT_SAVED") = "SIPA export completed and saved in {0}"
+magaegem("EN")("SIPA_EXPORT_NOT_SAVED") = "SIPA export completed. Not saved in a separate file."
+magaegem("ES") = CreateObject("Scripting.Dictionary")
+magaegem("ES")("IMPORT_COMPLETE") = "Importación completada."
+magaegem("ES")("EXPORT_COMPLETE") = "Exportación completada."
+magaegem("ES")("FILE_NOT_SELECTED") = "No se seleccionó ningún archivo. Operación cancelada."
+magaegem("ES")("DUPLICATE_VALUE") = "Se encontró un valor duplicado: {0} en la fila {1}. La operación ha sido abortada."
+magaegem("ES")("ALARM_NODE_NOT_FOUND") = "No se encontró el nodo 'Alarms' en el archivo XML."
+magaegem("ES")("MEMBER_NODE_NOT_FOUND") = "No se encontró el nodo 'Member' con Name='Alarms' en el archivo XML."
+magaegem("ES")("ROWS_HIDDEN") = "Proceso completado. Filas ocultadas: {0}"
+magaegem("ES")("ALL_ROWS_SHOWN") = "Todas las filas son ahora visibles."
+magaegem("ES")("SIPA_SHEET_NOT_FOUND") = "La hoja 'Per Supervisore SIPA' no existe en este libro. Por favor, cree esta hoja antes de continuar."
+magaegem("ES")("SIPA_EXPORT_COMPLETE") = "Exportación a SIPA completada."
+magaegem("ES")("SIPA_EXPORT_SAVED") = "Exportación a SIPA completada y guardada en {0}"
+magaegem("ES")("SIPA_EXPORT_NOT_SAVED") = "Exportación a SIPA completada. No se ha guardado en un archivo separado."
+magaegem("IT") = CreateObject("Scripting.Dictionary")
+magaegem("IT")("IMPORT_COMPLETE") = "Importazione completata."
+magaegem("IT")("EXPORT_COMPLETE") = "Esportazione completata."
+magaegem("IT")("FILE_NOT_SELECTED") = "Nessun file selezionato. Operazione annullata."
+magaegem("IT")("DUPLICATE_VALUE") = "È stato trovato un valore duplicato: {0} nella riga {1}. L'operazione è stata interrotta."
+magaegem("IT")("ALARM_NODE_NOT_FOUND") = "Il nodo 'Alarms' non è stato trovato nel file XML."
+magaegem("IT")("MEMBER_NODE_NOT_FOUND") = "Il nodo 'Member' con Name='Alarms' non è stato trovato nel file XML."
+magaegem("IT")("ROWS_HIDDEN") = "Processo completato. Righe nascoste: {0}"
+magaegem("IT")("ALL_ROWS_SHOWN") = "Tutte le righe sono ora visibili."
+magaegem("IT")("SIPA_SHEET_NOT_FOUND") = "Il foglio 'Per Supervisore SIPA' non esiste in questa cartella di lavoro. Si prega di creare questo foglio prima di continuare."
+magaegem("IT")("SIPA_EXPORT_COMPLETE") = "Esportazione SIPA completata."
+magaegem("IT")("SIPA_EXPORT_SAVED") = "Esportazione SIPA completata e salvata in {0}"
+magaegem("IT")("SIPA_EXPORT_NOT_SAVED") = "Esportazione SIPA completata. Non salvata in un file separato."
+Dim lang As String
+lang = GetExcelLanguage()
+If magaegem(lang).Exists(msgKey) Then
+GetTranslatedMessage = magaegem(lang)(msgKey)
+Else
+GetTranslatedMessage = magaegem("EN")(msgKey)
+End If
+End Function
\ No newline at end of file
diff --git a/Release/ImportExportDB5100 v0.3.xlsm b/Release/ImportExportDB5100 v0.3.xlsm
new file mode 100644
index 0000000..405f06a
Binary files /dev/null and b/Release/ImportExportDB5100 v0.3.xlsm differ
diff --git a/Release/ImportExportDB5100 v0.4.xlsm b/Release/ImportExportDB5100 v0.4.xlsm
new file mode 100644
index 0000000..657f5c5
Binary files /dev/null and b/Release/ImportExportDB5100 v0.4.xlsm differ
diff --git a/Release/ImportExportDB5100 v0.5.xlsm b/Release/ImportExportDB5100 v0.5.xlsm
new file mode 100644
index 0000000..ef4359b
Binary files /dev/null and b/Release/ImportExportDB5100 v0.5.xlsm differ
diff --git a/UDT SV Manager Allarm.xml b/UDT SV Manager Allarm.xml
new file mode 100644
index 0000000..51325ed
--- /dev/null
+++ b/UDT SV Manager Allarm.xml
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ High -> Higher priority
+
+
+
+
+ Section or Sections that belong
+
+
+
+
+
+
+ 0 : Error - 1 : Warning
+
+
+
+
+ In Seconds
+
+
+
+
+ UDT SV Manager Allarm
+
+
+
+
+
+
+
+ it-IT
+
+
+
+
+
+ en-GB
+
+
+
+
+
+ es-ES
+
+
+
+
+
+
+
+
+
+ it-IT
+
+
+
+
+
+ en-GB
+
+
+
+
+
+ es-ES
+
+
+
+
+
+
+
+
\ No newline at end of file