Con la funcio de exportacion funcionando
This commit is contained in:
parent
f40a9ee331
commit
f819f41016
|
@ -0,0 +1,230 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Document>
|
||||
<Engineering version="V19" />
|
||||
<SW.Blocks.GlobalDB ID="0">
|
||||
<AttributeList>
|
||||
<AutoNumber>false</AutoNumber>
|
||||
<Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
|
||||
<Section Name="Static">
|
||||
<Member Name="Alarms" Datatype="Array[0..1] of "UDT SV Manager Allarm"">
|
||||
<AttributeList>
|
||||
<BooleanAttribute Name="SetPoint" SystemDefined="true">true</BooleanAttribute>
|
||||
</AttributeList>
|
||||
<Sections>
|
||||
<Section Name="None">
|
||||
<Member Name="AlarmNum" Datatype="Int">
|
||||
<Subelement Path="0">
|
||||
<StartValue>0</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="1">
|
||||
<StartValue>0</StartValue>
|
||||
</Subelement>
|
||||
</Member>
|
||||
<Member Name="Source DB" Datatype="Int">
|
||||
<Subelement Path="0">
|
||||
<StartValue>0</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="1">
|
||||
<StartValue>0</StartValue>
|
||||
</Subelement>
|
||||
</Member>
|
||||
<Member Name="Source Byte" Datatype="Int">
|
||||
<Subelement Path="0">
|
||||
<StartValue>0</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="1">
|
||||
<StartValue>0</StartValue>
|
||||
</Subelement>
|
||||
</Member>
|
||||
<Member Name="Source Bit" Datatype="Byte">
|
||||
<Subelement Path="0">
|
||||
<StartValue>16#00</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="1">
|
||||
<StartValue>16#00</StartValue>
|
||||
</Subelement>
|
||||
</Member>
|
||||
<Member Name="Priority" Datatype="Byte">
|
||||
<Subelement Path="0">
|
||||
<StartValue>16#00</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="1">
|
||||
<StartValue>16#00</StartValue>
|
||||
</Subelement>
|
||||
</Member>
|
||||
<Member Name="Section" Datatype="Array[1.."Numero_Sezioni"] of Bool">
|
||||
<Subelement Path="0,1">
|
||||
<StartValue>FALSE</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="0,2">
|
||||
<StartValue>FALSE</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="0,3">
|
||||
<StartValue>FALSE</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="0,4">
|
||||
<StartValue>FALSE</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="0,5">
|
||||
<StartValue>FALSE</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="1,1">
|
||||
<StartValue>FALSE</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="1,2">
|
||||
<StartValue>FALSE</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="1,3">
|
||||
<StartValue>FALSE</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="1,4">
|
||||
<StartValue>FALSE</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="1,5">
|
||||
<StartValue>FALSE</StartValue>
|
||||
</Subelement>
|
||||
</Member>
|
||||
<Member Name="Value" Datatype="Bool">
|
||||
<Subelement Path="0">
|
||||
<StartValue>FALSE</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="1">
|
||||
<StartValue>FALSE</StartValue>
|
||||
</Subelement>
|
||||
</Member>
|
||||
<Member Name="Enable" Datatype="Bool">
|
||||
<Subelement Path="0">
|
||||
<StartValue>FALSE</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="1">
|
||||
<StartValue>FALSE</StartValue>
|
||||
</Subelement>
|
||||
</Member>
|
||||
<Member Name="Error / Warning" Datatype="Bool">
|
||||
<Subelement Path="0">
|
||||
<StartValue>FALSE</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="1">
|
||||
<StartValue>FALSE</StartValue>
|
||||
</Subelement>
|
||||
</Member>
|
||||
<Member Name="Ons" Datatype="Bool">
|
||||
<Subelement Path="0">
|
||||
<StartValue>FALSE</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="1">
|
||||
<StartValue>FALSE</StartValue>
|
||||
</Subelement>
|
||||
</Member>
|
||||
</Section>
|
||||
</Sections>
|
||||
<Subelement Path="0">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="it-IT">Coment1</MultiLanguageText>
|
||||
</Comment>
|
||||
</Subelement>
|
||||
<Subelement Path="1">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="it-IT">Coment2</MultiLanguageText>
|
||||
</Comment>
|
||||
</Subelement>
|
||||
</Member>
|
||||
<Member Name="SECTIONS" Datatype="Array[1.."Numero_Sezioni"] of "SIPA XDATA_Alarm_Sect_V04"">
|
||||
<AttributeList>
|
||||
<BooleanAttribute Name="SetPoint" SystemDefined="true">true</BooleanAttribute>
|
||||
</AttributeList>
|
||||
<Sections>
|
||||
<Section Name="None">
|
||||
<Member Name="GV_IOT_PRJ.cmm.i_wrn_nr" Datatype="Int">
|
||||
<Subelement Path="1">
|
||||
<StartValue>0</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="2">
|
||||
<StartValue>0</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="3">
|
||||
<StartValue>0</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="4">
|
||||
<StartValue>0</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="5">
|
||||
<StartValue>0</StartValue>
|
||||
</Subelement>
|
||||
</Member>
|
||||
<Member Name="GV_IOT_PRJ.cmm.i_alm_stp_nr" Datatype="Int">
|
||||
<Subelement Path="1">
|
||||
<StartValue>0</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="2">
|
||||
<StartValue>0</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="3">
|
||||
<StartValue>0</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="4">
|
||||
<StartValue>0</StartValue>
|
||||
</Subelement>
|
||||
<Subelement Path="5">
|
||||
<StartValue>0</StartValue>
|
||||
</Subelement>
|
||||
</Member>
|
||||
</Section>
|
||||
</Sections>
|
||||
</Member>
|
||||
</Section>
|
||||
</Sections></Interface>
|
||||
<MemoryLayout>Standard</MemoryLayout>
|
||||
<Name>DB Supervisor Manager</Name>
|
||||
<Namespace />
|
||||
<Number>5100</Number>
|
||||
<ProgrammingLanguage>DB</ProgrammingLanguage>
|
||||
</AttributeList>
|
||||
<ObjectList>
|
||||
<MultilingualText ID="1" CompositionName="Comment">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="2" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="3" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-GB</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="4" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
<MultilingualText ID="5" CompositionName="Title">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="6" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="7" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-GB</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="8" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
</ObjectList>
|
||||
</SW.Blocks.GlobalDB>
|
||||
</Document>
|
560
Funciones.bas
560
Funciones.bas
|
@ -68,16 +68,16 @@ Sub ImportSiemensXML()
|
|||
xmlDoc.Load (filePath)
|
||||
xmlDoc.SetProperty "SelectionNamespaces", "xmlns:a='http://www.siemens.com/automation/Openness/SW/Interface/v5'"
|
||||
|
||||
' Buscar el nodo "Allarms"
|
||||
Set alarmNode = xmlDoc.SelectSingleNode("//a:Member[@Name='Allarms']")
|
||||
' 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 'Allarms' en el archivo XML."
|
||||
MsgBox "No se encontró el nodo 'Alarms' en el archivo XML."
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
' Obtener los miembros del array "Allarms"
|
||||
' Obtener los miembros del array "Alarms"
|
||||
Set alarmArray = alarmNode.SelectNodes("a:Sections/a:Section/a:Member")
|
||||
|
||||
' Inicializar el desplazamiento de columna
|
||||
|
@ -129,7 +129,7 @@ Sub ImportSiemensXML()
|
|||
startValue = subElement.SelectSingleNode("a:StartValue").Text
|
||||
|
||||
' Escribir "X" o dejar vacío según el valor booleano
|
||||
ws.Cells(rowIndex, colIndex).value = TextBool(startValue)
|
||||
ws.Cells(rowIndex, colIndex).value = ImportBool(startValue)
|
||||
Next subElement
|
||||
|
||||
' Actualizar el desplazamiento de columna
|
||||
|
@ -150,7 +150,7 @@ Sub ImportSiemensXML()
|
|||
|
||||
' Si el tipo de dato es Bool, escribir "X" o dejar vacío
|
||||
If InStr(memberDataType, "Bool") > 0 Then
|
||||
ws.Cells(rowIndex, colOffset).value = TextBool(startValue)
|
||||
ws.Cells(rowIndex, colOffset).value = ImportBool(startValue)
|
||||
' Byte
|
||||
ElseIf InStr(memberDataType, "Byte") > 0 Then
|
||||
ws.Cells(rowIndex, colOffset).value = ImportByte(startValue)
|
||||
|
@ -168,7 +168,7 @@ Sub ImportSiemensXML()
|
|||
' Añadir la columna para las descripciones
|
||||
ws.Cells(primeraFila, colOffset).value = "Descripción"
|
||||
|
||||
' Obtener los subelementos directamente bajo "Allarms"
|
||||
' Obtener los subelementos directamente bajo "Alarms"
|
||||
Set subElements = alarmNode.SelectNodes("a:Subelement")
|
||||
|
||||
' Obtener el número de alarmas (filas)
|
||||
|
@ -192,37 +192,32 @@ Sub ImportSiemensXML()
|
|||
MsgBox "Importación completada."
|
||||
End Sub
|
||||
|
||||
|
||||
Sub ExportSiemensXML()
|
||||
Dim xmlDoc As Object
|
||||
Dim xmlNode As Object
|
||||
Dim alarmNode As Object
|
||||
Dim alarmArray As Object
|
||||
Dim i As Integer, j As Integer
|
||||
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 subElements As Object
|
||||
Dim subElement As Object
|
||||
Dim pathParts() As String
|
||||
Dim rowIndex As Integer
|
||||
Dim rowIndex As Variant
|
||||
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 cellValue As String
|
||||
Dim cellValue As Variant
|
||||
Dim startValueNode As Object
|
||||
Dim description As String
|
||||
Dim descriptionNode 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
|
||||
|
||||
primeraFila = 5
|
||||
primeraColumna = 2
|
||||
|
@ -258,419 +253,166 @@ Sub ExportSiemensXML()
|
|||
|
||||
Set ws = ThisWorkbook.Sheets(1)
|
||||
|
||||
' Calcular el número de alarmas considerando solo las filas visibles
|
||||
numAlarmas = 0
|
||||
Dim lastRow As Long
|
||||
lastRow = ws.Cells(ws.Rows.Count, primeraColumna).End(xlUp).Row
|
||||
|
||||
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 "Allarms"
|
||||
Set alarmNode = xmlDoc.SelectSingleNode("//a:Member[@Name='Allarms']")
|
||||
' Buscar el nodo "Member" con Name="Alarms"
|
||||
Set alarmsMemberNode = xmlDoc.SelectSingleNode("//a:Member[@Name='Alarms']")
|
||||
|
||||
' Verificar si se encontró el nodo
|
||||
If alarmNode Is Nothing Then
|
||||
MsgBox "No se encontró el nodo 'Allarms' en el archivo XML."
|
||||
If alarmsMemberNode Is Nothing Then
|
||||
MsgBox "No se encontró el nodo 'Member' con Name='Alarms' en el archivo XML."
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
' Obtener los miembros del array "Allarms"
|
||||
Set alarmArray = alarmNode.SelectNodes("a:Sections/a:Section/a:Member")
|
||||
' 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
|
||||
|
||||
' Inicializar el desplazamiento de columna
|
||||
colOffset = primeraColumna
|
||||
' 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
|
||||
|
||||
' Iterar sobre los miembros del array para determinar el desplazamiento de columna final
|
||||
For i = 0 To alarmArray.Length - 1
|
||||
memberName = alarmArray.item(i).Attributes.getNamedItem("Name").Text
|
||||
memberDataType = alarmArray.item(i).Attributes.getNamedItem("Datatype").Text
|
||||
datatypeText = regex.Replace(datatypeText, replacement)
|
||||
|
||||
If memberName = "Section" Then
|
||||
' Procesar el miembro "Section"
|
||||
' Obtener los subelementos
|
||||
Set subElements = alarmArray.item(i).SelectNodes("a:Subelement")
|
||||
' Actualizar el atributo Datatype
|
||||
alarmsMemberNode.Attributes.getNamedItem("Datatype").Text = datatypeText
|
||||
|
||||
' 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
|
||||
|
||||
' Actualizar el desplazamiento de columna
|
||||
colOffset = colOffset + maxSectionIndex
|
||||
Else
|
||||
' Actualizar el desplazamiento de columna
|
||||
colOffset = colOffset + 1
|
||||
End If
|
||||
' 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
|
||||
|
||||
' Ahora colOffset está en la posición de la columna de descripciones
|
||||
Dim descriptionCol As Integer
|
||||
descriptionCol = colOffset
|
||||
|
||||
' Reiniciar colOffset para comenzar desde la primera columna de datos
|
||||
colOffset = primeraColumna
|
||||
|
||||
' Iterar sobre los miembros del array nuevamente para exportar los datos
|
||||
For i = 0 To alarmArray.Length - 1
|
||||
memberName = alarmArray.item(i).Attributes.getNamedItem("Name").Text
|
||||
memberDataType = alarmArray.item(i).Attributes.getNamedItem("Datatype").Text
|
||||
|
||||
If memberName = "Section" Then
|
||||
' Procesar el miembro "Section"
|
||||
' 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
|
||||
|
||||
' Leer los valores de Excel y actualizar el XML
|
||||
For Each subElement In subElements
|
||||
' Obtener el atributo "Path"
|
||||
pathParts = Split(subElement.Attributes.getNamedItem("Path").Text, ",")
|
||||
' Calcular el índice de fila en Excel
|
||||
rowIndex = CInt(pathParts(0)) + primeraFila + 1
|
||||
|
||||
' Verificar si la fila está oculta
|
||||
If Not ws.Rows(rowIndex).Hidden Then
|
||||
' Calcular el índice de columna
|
||||
sectionIndex = CInt(pathParts(1))
|
||||
colIndex = colOffset + sectionIndex - 1
|
||||
|
||||
' Leer el valor de la celda
|
||||
cellValue = ws.Cells(rowIndex, colIndex).value
|
||||
|
||||
' Convertir "X" a "TRUE", otros a "FALSE"
|
||||
cellValue = BoolText(Trim(cellValue))
|
||||
|
||||
' Actualizar el valor en el XML
|
||||
Set startValueNode = subElement.SelectSingleNode("a:StartValue")
|
||||
startValueNode.Text = cellValue
|
||||
End If
|
||||
Next subElement
|
||||
|
||||
' Actualizar el desplazamiento de columna
|
||||
colOffset = colOffset + maxSectionIndex
|
||||
Else
|
||||
' Procesar otros miembros normalmente
|
||||
' Leer los valores de Excel y actualizar el XML
|
||||
Set subElements = alarmArray.item(i).SelectNodes("a:Subelement")
|
||||
For j = 0 To subElements.Length - 1
|
||||
' Índice de fila en Excel
|
||||
rowIndex = j + primeraFila + 1
|
||||
|
||||
' Verificar si la fila está oculta
|
||||
If Not ws.Rows(rowIndex).Hidden Then
|
||||
' Leer el valor de la celda
|
||||
cellValue = ws.Cells(rowIndex, colOffset).value
|
||||
|
||||
' Si el tipo de dato es Bool, convertir "X" a "TRUE", otros a "FALSE"
|
||||
If InStr(memberDataType, "Bool") > 0 Then
|
||||
cellValue = BoolText(Trim(cellValue))
|
||||
ElseIf InStr(memberDataType, "Byte") > 0 Then
|
||||
cellValue = ExportByte(cellValue)
|
||||
' 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
|
||||
|
||||
' Actualizar el valor en el XML
|
||||
Set startValueNode = subElements.item(j).SelectSingleNode("a:StartValue")
|
||||
startValueNode.Text = cellValue
|
||||
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", "Source DB", "Source Byte", "Source Bit", "Priority", "Section", "Value", "Enable", "Error / Warning", "Ons")
|
||||
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 + i + j - 1).value
|
||||
startValueNode.Text = IIf(UCase(Trim(cellValue)) = "X", "TRUE", "FALSE")
|
||||
|
||||
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)
|
||||
|
||||
' Actualizar el desplazamiento de columna
|
||||
colOffset = colOffset + 1
|
||||
Set startValueNode = xmlDoc.createNode(1, "StartValue", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
|
||||
cellValue = ws.Cells(rowIndex, primeraColumna + i).value
|
||||
|
||||
Select Case dataTypes(i)
|
||||
Case "Bool"
|
||||
startValueNode.Text = IIf(UCase(Trim(cellValue)) = "X", "TRUE", "FALSE")
|
||||
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
|
||||
|
||||
' Actualizar las descripciones en el XML
|
||||
' Obtener los subelementos directamente bajo "Allarms"
|
||||
Set subElements = alarmNode.SelectNodes("a:Subelement")
|
||||
' Añadir los comentarios
|
||||
Dim commentColumn As Integer
|
||||
commentColumn = ws.Cells(primeraFila, ws.Columns.Count).End(xlToLeft).Column
|
||||
|
||||
' Obtener el número de alarmas (filas)
|
||||
Dim numAlarmas As Integer
|
||||
numAlarmas = subElements.Length
|
||||
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)
|
||||
|
||||
' Actualizar las descripciones en el XML
|
||||
For j = 0 To numAlarmas - 1
|
||||
' Índice de fila en Excel
|
||||
rowIndex = primeraFila + j + 1
|
||||
|
||||
' Verificar si la fila está oculta
|
||||
If Not ws.Rows(rowIndex).Hidden Then
|
||||
' Leer la descripción de la celda en Excel
|
||||
description = ws.Cells(rowIndex, descriptionCol).value
|
||||
|
||||
' Obtener o crear el nodo de descripción para cada alarma
|
||||
Set descriptionNode = subElements.item(j).SelectSingleNode("a:Comment/a:MultiLanguageText")
|
||||
If descriptionNode Is Nothing Then
|
||||
' Crear el nodo de descripción si no existe
|
||||
Set descriptionNode = xmlDoc.createElement("MultiLanguageText")
|
||||
descriptionNode.Text = description
|
||||
descriptionNode.setAttribute "Lang", "it-IT" ' Ajusta el idioma según tus necesidades
|
||||
|
||||
' Crear el nodo padre "Comment" si no existe
|
||||
Dim commentNode As Object
|
||||
Set commentNode = subElements.item(j).SelectSingleNode("a:Comment")
|
||||
If commentNode Is Nothing Then
|
||||
Set commentNode = xmlDoc.createElement("Comment")
|
||||
subElements.item(j).appendChild commentNode
|
||||
End If
|
||||
Set commentNode = xmlDoc.createNode(1, "Comment", "http://www.siemens.com/automation/Openness/SW/Interface/v5")
|
||||
|
||||
commentNode.appendChild descriptionNode
|
||||
Else
|
||||
' Actualizar el texto de la descripción
|
||||
descriptionNode.Text = description
|
||||
End If
|
||||
End If
|
||||
Next j
|
||||
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."
|
||||
MsgBox "Exportación completada. Exportadas " + Str(numAlarmas) + " Filas."
|
||||
End Sub
|
||||
|
||||
|
||||
Sub GenerateSiemensXML()
|
||||
Dim xmlDoc As Object
|
||||
Dim rootNode As Object
|
||||
Dim documentNode As Object
|
||||
Dim xmlDeclaration As Object
|
||||
Dim alarmNode As Object
|
||||
Dim alarmsSectionsNode As Object
|
||||
Dim alarmsSectionNode As Object
|
||||
Dim newMemberNode As Object
|
||||
Dim subElementNode As Object
|
||||
Dim startValueNode As Object
|
||||
Dim commentNode As Object
|
||||
Dim multiLanguageTextNode As Object
|
||||
Dim attributeListNode As Object
|
||||
Dim nameNode As Object
|
||||
Dim i As Integer, j As Integer
|
||||
Dim ws As Worksheet
|
||||
Dim filePath As String
|
||||
|
||||
Dim primeraFila As Integer, primeraColumna As Integer
|
||||
Dim numAlarmas As Integer
|
||||
Dim colOffset As Integer
|
||||
Dim memberName As String
|
||||
Dim memberDataType As String
|
||||
Dim colIndex As Integer
|
||||
Dim rowIndex As Integer
|
||||
Dim cellValue As String
|
||||
Dim description As String
|
||||
Dim decimalValue As Long
|
||||
Dim hexValue As String
|
||||
Dim maxSectionIndex As Integer
|
||||
Dim sectionIndex As Integer
|
||||
|
||||
primeraFila = 5
|
||||
primeraColumna = 2
|
||||
|
||||
' Pedir al usuario que seleccione la ubicación para guardar el archivo XML
|
||||
filePath = Application.GetSaveAsFilename("NuevoArchivo.xml", "Archivos XML (*.xml), *.xml", , "Guardar archivo XML")
|
||||
|
||||
' Verificar si se seleccionó una ruta
|
||||
If filePath = "False" Or filePath = "Falso" Then
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
Set ws = ThisWorkbook.Sheets(1)
|
||||
|
||||
' Crear el documento XML
|
||||
Set xmlDoc = CreateObject("MSXML2.DOMDocument")
|
||||
xmlDoc.async = False
|
||||
|
||||
' Añadir la declaración XML
|
||||
Set xmlDeclaration = xmlDoc.createProcessingInstruction("xml", "version='1.0' encoding='UTF-8'")
|
||||
xmlDoc.appendChild xmlDeclaration
|
||||
|
||||
' Crear el nodo raíz
|
||||
Set rootNode = xmlDoc.createElement("Document")
|
||||
xmlDoc.appendChild rootNode
|
||||
|
||||
' Añadir el nodo de información del documento (opcional)
|
||||
Set documentNode = xmlDoc.createElement("DocumentInfo")
|
||||
rootNode.appendChild documentNode
|
||||
|
||||
' Aquí puedes añadir más información al DocumentInfo si lo deseas
|
||||
|
||||
' Crear el nodo "SW.DT"
|
||||
Set alarmNode = xmlDoc.createElement("SW.DT")
|
||||
alarmNode.setAttribute "ID", "0"
|
||||
rootNode.appendChild alarmNode
|
||||
|
||||
' Crear el nodo "AttributeList" dentro de "SW.DT"
|
||||
Set attributeListNode = xmlDoc.createElement("AttributeList")
|
||||
alarmNode.appendChild attributeListNode
|
||||
|
||||
' Añadir los atributos necesarios (Nombre, Comentario, etc.)
|
||||
Set nameNode = xmlDoc.createElement("Name")
|
||||
nameNode.Text = "AllarmsDB"
|
||||
attributeListNode.appendChild nameNode
|
||||
|
||||
' Añadir más atributos según sea necesario
|
||||
|
||||
' Crear el nodo "Sections" dentro de "SW.DT"
|
||||
Set sectionsNode = xmlDoc.createElement("Sections")
|
||||
alarmNode.appendChild sectionsNode
|
||||
|
||||
' Crear la sección "Static"
|
||||
Set sectionNode = xmlDoc.createElement("Section")
|
||||
sectionNode.setAttribute "Name", "Static"
|
||||
sectionsNode.appendChild sectionNode
|
||||
|
||||
' Crear el miembro "Allarms"
|
||||
Set memberNode = xmlDoc.createElement("Member")
|
||||
memberNode.setAttribute "Name", "Allarms"
|
||||
memberNode.setAttribute "Datatype", "Array"
|
||||
sectionNode.appendChild memberNode
|
||||
|
||||
' Crear los nodos necesarios dentro de "Allarms"
|
||||
' Aquí asumiremos que tienes una estructura similar a la del XML original
|
||||
|
||||
' Crear "Sections" dentro de "Allarms"
|
||||
Set alarmsSectionsNode = xmlDoc.createElement("Sections")
|
||||
memberNode.appendChild alarmsSectionsNode
|
||||
|
||||
' Crear "Section" dentro de "Sections" de "Allarms"
|
||||
Set alarmsSectionNode = xmlDoc.createElement("Section")
|
||||
alarmsSectionNode.setAttribute "Name", "Member"
|
||||
alarmsSectionsNode.appendChild alarmsSectionNode
|
||||
|
||||
' Ahora añadiremos los miembros (campos) de cada alarma
|
||||
' Primero, obtenemos los nombres de los miembros desde las columnas en Excel
|
||||
Dim columnNames As Collection
|
||||
Set columnNames = New Collection
|
||||
|
||||
colOffset = primeraColumna
|
||||
Do While ws.Cells(primeraFila, colOffset).value <> ""
|
||||
columnNames.Add ws.Cells(primeraFila, colOffset).value
|
||||
colOffset = colOffset + 1
|
||||
Loop
|
||||
|
||||
' Determinar el número de alarmas (filas)
|
||||
numAlarmas = ws.Cells(ws.Rows.Count, primeraColumna).End(xlUp).Row - (primeraFila + 1) + 1
|
||||
|
||||
' Ahora, creamos los miembros dentro de "Allarms"
|
||||
Dim membersCollection As Collection
|
||||
Set membersCollection = New Collection
|
||||
|
||||
' Colección para almacenar los tipos de datos
|
||||
Dim memberDataTypes As Collection
|
||||
Set memberDataTypes = New Collection
|
||||
|
||||
For i = 1 To columnNames.Count
|
||||
memberName = columnNames(i)
|
||||
' Determinar el tipo de dato basado en el nombre de la columna o alguna otra lógica
|
||||
' Aquí asumiremos que tienes una manera de determinar el tipo de dato
|
||||
' Por simplicidad, asumiremos que todos son Bool excepto "Descripción" y "Section.X"
|
||||
|
||||
If Left(memberName, 8) = "Section." Then
|
||||
memberDataType = "Bool"
|
||||
ElseIf memberName = "Descripción" Then
|
||||
memberDataType = "String"
|
||||
Else
|
||||
memberDataType = "Bool"
|
||||
End If
|
||||
|
||||
' Crear el miembro
|
||||
Set newMemberNode = xmlDoc.createElement("Member")
|
||||
newMemberNode.setAttribute "Name", memberName
|
||||
newMemberNode.setAttribute "Datatype", memberDataType
|
||||
alarmsSectionNode.appendChild newMemberNode
|
||||
|
||||
' Añadir a las colecciones
|
||||
membersCollection.Add newMemberNode
|
||||
memberDataTypes.Add memberDataType
|
||||
Next i
|
||||
|
||||
' Ahora, añadimos los subelementos (valores) para cada alarma
|
||||
For j = 1 To numAlarmas
|
||||
rowIndex = primeraFila + j
|
||||
|
||||
' Verificar si la fila está oculta
|
||||
If Not ws.Rows(rowIndex).Hidden Then
|
||||
For i = 1 To membersCollection.Count
|
||||
memberName = columnNames(i)
|
||||
Set newMemberNode = membersCollection(i)
|
||||
memberDataType = memberDataTypes(i)
|
||||
|
||||
' Crear el subelemento
|
||||
Set subElementNode = xmlDoc.createElement("Subelement")
|
||||
subElementNode.setAttribute "Path", CStr(j - 1)
|
||||
newMemberNode.appendChild subElementNode
|
||||
|
||||
' Leer el valor de la celda
|
||||
colIndex = primeraColumna + i - 1
|
||||
cellValue = ws.Cells(rowIndex, colIndex).value
|
||||
|
||||
' Crear el nodo "StartValue"
|
||||
Set startValueNode = xmlDoc.createElement("StartValue")
|
||||
|
||||
' Manejar los diferentes tipos de datos
|
||||
If Left(memberName, 8) = "Section." Or memberDataType = "Bool" Then
|
||||
' Convertir "X" a "TRUE", otros a "FALSE"
|
||||
If UCase(Trim(cellValue)) = "X" Then
|
||||
startValueNode.Text = "TRUE"
|
||||
Else
|
||||
startValueNode.Text = "FALSE"
|
||||
End If
|
||||
ElseIf memberDataType = "Byte" Then
|
||||
' Convertir decimal a "16#xx"
|
||||
If IsNumeric(cellValue) Then
|
||||
decimalValue = CLng(cellValue)
|
||||
hexValue = Hex(decimalValue)
|
||||
If Len(hexValue) < 2 Then
|
||||
hexValue = "0" & hexValue
|
||||
End If
|
||||
startValueNode.Text = "16#" & hexValue
|
||||
Else
|
||||
startValueNode.Text = "16#00"
|
||||
End If
|
||||
Else
|
||||
' Otros tipos de datos
|
||||
startValueNode.Text = CStr(cellValue)
|
||||
End If
|
||||
|
||||
subElementNode.appendChild startValueNode
|
||||
|
||||
' Si es el campo "Descripción", agregar el nodo de comentario
|
||||
If memberName = "Descripción" Then
|
||||
Set commentNode = xmlDoc.createElement("Comment")
|
||||
Set multiLanguageTextNode = xmlDoc.createElement("MultiLanguageText")
|
||||
multiLanguageTextNode.setAttribute "Lang", "it-IT" ' Ajusta el idioma según sea necesario
|
||||
multiLanguageTextNode.Text = CStr(cellValue)
|
||||
commentNode.appendChild multiLanguageTextNode
|
||||
subElementNode.appendChild commentNode
|
||||
End If
|
||||
Next i
|
||||
End If
|
||||
Next j
|
||||
|
||||
' Guardar el archivo XML
|
||||
xmlDoc.Save filePath
|
||||
|
||||
MsgBox "Archivo XML generado exitosamente."
|
||||
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
|
||||
|
@ -723,23 +465,23 @@ Sub QuickSort(arr As Variant, first As Long, last As Long)
|
|||
If low < last Then QuickSort arr, low, last
|
||||
End Sub
|
||||
|
||||
Function TextBool(startValue As String)
|
||||
Function ImportBool(startValue)
|
||||
' Escribir "X" o dejar vacío según el valor booleano
|
||||
TextBool = " "
|
||||
ImportBool = " "
|
||||
If UCase(startValue) = "TRUE" Or UCase(startValue) = "1" Then
|
||||
TextBool = "X"
|
||||
ImportBool = "X"
|
||||
End If
|
||||
End Function
|
||||
|
||||
Function BoolText(excelValue As String)
|
||||
Function ExportBool(excelValue)
|
||||
' Escribir "X" o dejar vacío según el valor booleano
|
||||
BoolText = "FALSE"
|
||||
ExportBool = "FALSE"
|
||||
If UCase(excelValue) = "X" Or UCase(excelValue) = "TRUE" Or UCase(excelValue) = "1" Then
|
||||
BoolText = "TRUE"
|
||||
ExportBool = "TRUE"
|
||||
End If
|
||||
End Function
|
||||
|
||||
Function ImportByte(startValue As String)
|
||||
Function ImportByte(startValue)
|
||||
If Left(startValue, 3) = "16#" Then
|
||||
' Extraer el valor hexadecimal
|
||||
hexValue = Mid(startValue, 4)
|
||||
|
@ -751,7 +493,7 @@ Function ImportByte(startValue As String)
|
|||
End If
|
||||
End Function
|
||||
|
||||
Function ExportByte(cellValue As String)
|
||||
Function ExportByte(cellValue)
|
||||
' Es Byte, convertir de decimal a hexadecimal en formato "16#xx"
|
||||
If IsNumeric(cellValue) Then
|
||||
decimalValue = CLng(cellValue)
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue