You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
506 lines
19 KiB
506 lines
19 KiB
Imports System.Data
|
|
Imports System.Data.SqlClient
|
|
Imports System.Data.SqlTypes
|
|
Imports System.IO
|
|
Imports System.Reflection
|
|
Imports System.Xml
|
|
Public Class Form1
|
|
Inherits System.Windows.Forms.Form
|
|
|
|
#Region " Vom Windows Form Designer generierter Code "
|
|
|
|
Public Sub New()
|
|
MyBase.New()
|
|
|
|
' Dieser Aufruf ist für den Windows Form-Designer erforderlich.
|
|
InitializeComponent()
|
|
|
|
' Initialisierungen nach dem Aufruf InitializeComponent() hinzufügen
|
|
|
|
End Sub
|
|
|
|
' Die Form überschreibt den Löschvorgang der Basisklasse, um Komponenten zu bereinigen.
|
|
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
|
|
If disposing Then
|
|
If Not (components Is Nothing) Then
|
|
components.Dispose()
|
|
End If
|
|
End If
|
|
MyBase.Dispose(disposing)
|
|
End Sub
|
|
|
|
' Für Windows Form-Designer erforderlich
|
|
Private components As System.ComponentModel.IContainer
|
|
|
|
'HINWEIS: Die folgende Prozedur ist für den Windows Form-Designer erforderlich
|
|
'Sie kann mit dem Windows Form-Designer modifiziert werden.
|
|
'Verwenden Sie nicht den Code-Editor zur Bearbeitung.
|
|
Friend WithEvents OpenFileDialog1 As System.Windows.Forms.OpenFileDialog
|
|
Friend WithEvents Button1 As System.Windows.Forms.Button
|
|
Friend WithEvents Label1 As System.Windows.Forms.Label
|
|
Friend WithEvents Button2 As System.Windows.Forms.Button
|
|
Friend WithEvents Label2 As System.Windows.Forms.Label
|
|
Friend WithEvents TxtTable As System.Windows.Forms.TextBox
|
|
Friend WithEvents Label3 As System.Windows.Forms.Label
|
|
Friend WithEvents TxtKeyField As System.Windows.Forms.TextBox
|
|
Friend WithEvents TxtKeyValue As System.Windows.Forms.TextBox
|
|
Friend WithEvents KeyFeld As System.Windows.Forms.Label
|
|
Friend WithEvents Label4 As System.Windows.Forms.Label
|
|
Friend WithEvents Label5 As System.Windows.Forms.Label
|
|
Friend WithEvents Button3 As System.Windows.Forms.Button
|
|
Friend WithEvents Button4 As System.Windows.Forms.Button
|
|
Friend WithEvents txtConnstring As System.Windows.Forms.TextBox
|
|
Friend WithEvents txtFilename As System.Windows.Forms.TextBox
|
|
Friend WithEvents txtBindDatafeld As System.Windows.Forms.TextBox
|
|
Friend WithEvents cbstring As System.Windows.Forms.CheckBox
|
|
Friend WithEvents MainMenu1 As System.Windows.Forms.MainMenu
|
|
Friend WithEvents MenuItem1 As System.Windows.Forms.MenuItem
|
|
Friend WithEvents MenuItem3 As MenuItem
|
|
Friend WithEvents MenuItem2 As System.Windows.Forms.MenuItem
|
|
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
|
|
Me.components = New System.ComponentModel.Container()
|
|
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(Form1))
|
|
Me.OpenFileDialog1 = New System.Windows.Forms.OpenFileDialog()
|
|
Me.Button1 = New System.Windows.Forms.Button()
|
|
Me.txtConnstring = New System.Windows.Forms.TextBox()
|
|
Me.Label1 = New System.Windows.Forms.Label()
|
|
Me.txtFilename = New System.Windows.Forms.TextBox()
|
|
Me.Button2 = New System.Windows.Forms.Button()
|
|
Me.Label2 = New System.Windows.Forms.Label()
|
|
Me.TxtTable = New System.Windows.Forms.TextBox()
|
|
Me.Label3 = New System.Windows.Forms.Label()
|
|
Me.TxtKeyField = New System.Windows.Forms.TextBox()
|
|
Me.TxtKeyValue = New System.Windows.Forms.TextBox()
|
|
Me.KeyFeld = New System.Windows.Forms.Label()
|
|
Me.Label4 = New System.Windows.Forms.Label()
|
|
Me.txtBindDatafeld = New System.Windows.Forms.TextBox()
|
|
Me.Label5 = New System.Windows.Forms.Label()
|
|
Me.Button3 = New System.Windows.Forms.Button()
|
|
Me.Button4 = New System.Windows.Forms.Button()
|
|
Me.cbstring = New System.Windows.Forms.CheckBox()
|
|
Me.MainMenu1 = New System.Windows.Forms.MainMenu(Me.components)
|
|
Me.MenuItem1 = New System.Windows.Forms.MenuItem()
|
|
Me.MenuItem2 = New System.Windows.Forms.MenuItem()
|
|
Me.MenuItem3 = New System.Windows.Forms.MenuItem()
|
|
Me.SuspendLayout()
|
|
'
|
|
'Button1
|
|
'
|
|
Me.Button1.Image = CType(resources.GetObject("Button1.Image"), System.Drawing.Image)
|
|
Me.Button1.Location = New System.Drawing.Point(584, 8)
|
|
Me.Button1.Name = "Button1"
|
|
Me.Button1.Size = New System.Drawing.Size(24, 24)
|
|
Me.Button1.TabIndex = 2
|
|
Me.Button1.Visible = False
|
|
'
|
|
'txtConnstring
|
|
'
|
|
Me.txtConnstring.Location = New System.Drawing.Point(112, 8)
|
|
Me.txtConnstring.Name = "txtConnstring"
|
|
Me.txtConnstring.Size = New System.Drawing.Size(472, 20)
|
|
Me.txtConnstring.TabIndex = 3
|
|
'
|
|
'Label1
|
|
'
|
|
Me.Label1.Location = New System.Drawing.Point(8, 8)
|
|
Me.Label1.Name = "Label1"
|
|
Me.Label1.Size = New System.Drawing.Size(100, 23)
|
|
Me.Label1.TabIndex = 4
|
|
Me.Label1.Text = "Connestionstring"
|
|
'
|
|
'txtFilename
|
|
'
|
|
Me.txtFilename.Location = New System.Drawing.Point(112, 32)
|
|
Me.txtFilename.Name = "txtFilename"
|
|
Me.txtFilename.Size = New System.Drawing.Size(472, 20)
|
|
Me.txtFilename.TabIndex = 5
|
|
Me.txtFilename.Text = "c:\temp\testdata."
|
|
'
|
|
'Button2
|
|
'
|
|
Me.Button2.Image = CType(resources.GetObject("Button2.Image"), System.Drawing.Image)
|
|
Me.Button2.Location = New System.Drawing.Point(584, 32)
|
|
Me.Button2.Name = "Button2"
|
|
Me.Button2.Size = New System.Drawing.Size(24, 23)
|
|
Me.Button2.TabIndex = 6
|
|
'
|
|
'Label2
|
|
'
|
|
Me.Label2.Location = New System.Drawing.Point(8, 32)
|
|
Me.Label2.Name = "Label2"
|
|
Me.Label2.Size = New System.Drawing.Size(100, 23)
|
|
Me.Label2.TabIndex = 7
|
|
Me.Label2.Text = "Dateiname"
|
|
'
|
|
'TxtTable
|
|
'
|
|
Me.TxtTable.Location = New System.Drawing.Point(112, 80)
|
|
Me.TxtTable.Name = "TxtTable"
|
|
Me.TxtTable.Size = New System.Drawing.Size(472, 20)
|
|
Me.TxtTable.TabIndex = 8
|
|
'
|
|
'Label3
|
|
'
|
|
Me.Label3.Location = New System.Drawing.Point(8, 80)
|
|
Me.Label3.Name = "Label3"
|
|
Me.Label3.Size = New System.Drawing.Size(100, 23)
|
|
Me.Label3.TabIndex = 9
|
|
Me.Label3.Text = "Tabelle"
|
|
'
|
|
'TxtKeyField
|
|
'
|
|
Me.TxtKeyField.Location = New System.Drawing.Point(112, 104)
|
|
Me.TxtKeyField.Name = "TxtKeyField"
|
|
Me.TxtKeyField.Size = New System.Drawing.Size(472, 20)
|
|
Me.TxtKeyField.TabIndex = 10
|
|
'
|
|
'TxtKeyValue
|
|
'
|
|
Me.TxtKeyValue.Location = New System.Drawing.Point(112, 128)
|
|
Me.TxtKeyValue.Name = "TxtKeyValue"
|
|
Me.TxtKeyValue.Size = New System.Drawing.Size(352, 20)
|
|
Me.TxtKeyValue.TabIndex = 11
|
|
'
|
|
'KeyFeld
|
|
'
|
|
Me.KeyFeld.Location = New System.Drawing.Point(8, 104)
|
|
Me.KeyFeld.Name = "KeyFeld"
|
|
Me.KeyFeld.Size = New System.Drawing.Size(100, 23)
|
|
Me.KeyFeld.TabIndex = 12
|
|
Me.KeyFeld.Text = "Key-Feld"
|
|
'
|
|
'Label4
|
|
'
|
|
Me.Label4.Location = New System.Drawing.Point(8, 128)
|
|
Me.Label4.Name = "Label4"
|
|
Me.Label4.Size = New System.Drawing.Size(100, 23)
|
|
Me.Label4.TabIndex = 13
|
|
Me.Label4.Text = "Key-Value"
|
|
'
|
|
'txtBindDatafeld
|
|
'
|
|
Me.txtBindDatafeld.Location = New System.Drawing.Point(112, 152)
|
|
Me.txtBindDatafeld.Name = "txtBindDatafeld"
|
|
Me.txtBindDatafeld.Size = New System.Drawing.Size(472, 20)
|
|
Me.txtBindDatafeld.TabIndex = 14
|
|
'
|
|
'Label5
|
|
'
|
|
Me.Label5.Location = New System.Drawing.Point(8, 152)
|
|
Me.Label5.Name = "Label5"
|
|
Me.Label5.Size = New System.Drawing.Size(100, 23)
|
|
Me.Label5.TabIndex = 15
|
|
Me.Label5.Text = "Bin-Datafeld"
|
|
'
|
|
'Button3
|
|
'
|
|
Me.Button3.Location = New System.Drawing.Point(112, 200)
|
|
Me.Button3.Name = "Button3"
|
|
Me.Button3.Size = New System.Drawing.Size(120, 40)
|
|
Me.Button3.TabIndex = 16
|
|
Me.Button3.Text = "DB -> Datei"
|
|
'
|
|
'Button4
|
|
'
|
|
Me.Button4.Location = New System.Drawing.Point(464, 200)
|
|
Me.Button4.Name = "Button4"
|
|
Me.Button4.Size = New System.Drawing.Size(120, 40)
|
|
Me.Button4.TabIndex = 17
|
|
Me.Button4.Text = "Datei -> DB"
|
|
'
|
|
'cbstring
|
|
'
|
|
Me.cbstring.Location = New System.Drawing.Point(488, 128)
|
|
Me.cbstring.Name = "cbstring"
|
|
Me.cbstring.Size = New System.Drawing.Size(104, 24)
|
|
Me.cbstring.TabIndex = 19
|
|
Me.cbstring.Text = "String"
|
|
'
|
|
'MainMenu1
|
|
'
|
|
Me.MainMenu1.MenuItems.AddRange(New System.Windows.Forms.MenuItem() {Me.MenuItem1, Me.MenuItem3})
|
|
'
|
|
'MenuItem1
|
|
'
|
|
Me.MenuItem1.Index = 0
|
|
Me.MenuItem1.MenuItems.AddRange(New System.Windows.Forms.MenuItem() {Me.MenuItem2})
|
|
Me.MenuItem1.Text = "&Datei"
|
|
'
|
|
'MenuItem2
|
|
'
|
|
Me.MenuItem2.Index = 0
|
|
Me.MenuItem2.Text = "&Beenden"
|
|
'
|
|
'MenuItem3
|
|
'
|
|
Me.MenuItem3.Index = 1
|
|
Me.MenuItem3.Text = "&Datei-Verarbeitung"
|
|
'
|
|
'Form1
|
|
'
|
|
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
|
|
Me.ClientSize = New System.Drawing.Size(624, 249)
|
|
Me.Controls.Add(Me.cbstring)
|
|
Me.Controls.Add(Me.Button4)
|
|
Me.Controls.Add(Me.Button3)
|
|
Me.Controls.Add(Me.Label5)
|
|
Me.Controls.Add(Me.txtBindDatafeld)
|
|
Me.Controls.Add(Me.Label4)
|
|
Me.Controls.Add(Me.KeyFeld)
|
|
Me.Controls.Add(Me.TxtKeyValue)
|
|
Me.Controls.Add(Me.TxtKeyField)
|
|
Me.Controls.Add(Me.Label3)
|
|
Me.Controls.Add(Me.TxtTable)
|
|
Me.Controls.Add(Me.Label2)
|
|
Me.Controls.Add(Me.Button2)
|
|
Me.Controls.Add(Me.txtFilename)
|
|
Me.Controls.Add(Me.Label1)
|
|
Me.Controls.Add(Me.txtConnstring)
|
|
Me.Controls.Add(Me.Button1)
|
|
Me.Menu = Me.MainMenu1
|
|
Me.Name = "Form1"
|
|
Me.Text = "SQL-BinData"
|
|
Me.ResumeLayout(False)
|
|
Me.PerformLayout()
|
|
|
|
End Sub
|
|
|
|
#End Region
|
|
|
|
Public args As String() = Environment.GetCommandLineArgs()
|
|
|
|
|
|
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
|
|
Load_Data()
|
|
End Sub
|
|
|
|
Private Sub Load_Data(Optional with_message As Boolean = True)
|
|
Dim dsdata As New DataSet
|
|
Dim filename As String = Me.txtFilename.Text
|
|
Dim sql As String = ""
|
|
sql = "Select * from " + Me.TxtTable.Text
|
|
sql = sql & " where " + Me.TxtKeyField.Text
|
|
sql = sql & "="
|
|
If Me.cbstring.Checked = True Then sql = sql & "'"
|
|
sql = sql & Me.TxtKeyValue.Text
|
|
If Me.cbstring.Checked = True Then sql = sql & "'"
|
|
Try
|
|
dsdata.Tables.Clear()
|
|
Dim connection As New SqlConnection
|
|
Dim da As New SqlDataAdapter(sql, connection)
|
|
Dim cb As SqlCommandBuilder = New SqlCommandBuilder(da)
|
|
Dim ds As New DataSet
|
|
Try
|
|
connection.ConnectionString = Me.txtConnstring.Text
|
|
connection.Open()
|
|
da.Fill(ds, "Daten")
|
|
Dim myrow As DataRow
|
|
If ds.Tables(0).Rows.Count = 0 Then
|
|
MsgBox("Empfänger konnten nicht geladen werden.")
|
|
Else
|
|
If ds.Tables(0).Rows.Count > 1 Then
|
|
MsgBox("Mehr als ein Datensatz ausgewählt.", MsgBoxStyle.Exclamation)
|
|
Else
|
|
Dim i As Integer
|
|
Dim idatafield As Integer = -1
|
|
|
|
For i = 0 To ds.Tables(0).Columns.Count - 1
|
|
If UCase(ds.Tables(0).Columns(i).Caption) = UCase(Me.txtBindDatafeld.Text) Then
|
|
idatafield = i
|
|
End If
|
|
Next
|
|
If idatafield > -1 Then
|
|
myrow = ds.Tables(0).Rows(0)
|
|
|
|
Dim MyData() As Byte
|
|
MyData = myrow.Item(idatafield)
|
|
Dim K As Long
|
|
K = UBound(MyData)
|
|
Dim fs As New FileStream(Me.txtFilename.Text, FileMode.OpenOrCreate, FileAccess.Write)
|
|
fs.Write(MyData, 0, K)
|
|
fs.Close()
|
|
fs = Nothing
|
|
Else
|
|
MsgBox("Bin-Datenfeld in der Tabelle nicht vorhanden", MsgBoxStyle.Exclamation)
|
|
End If
|
|
End If
|
|
End If
|
|
|
|
Catch ex As Exception
|
|
MsgBox("Ein Fehler ist aufgetreten" + ex.Message)
|
|
Finally
|
|
cb = Nothing
|
|
ds = Nothing
|
|
da = Nothing
|
|
connection.Close()
|
|
connection = Nothing
|
|
End Try
|
|
Catch ex As Exception
|
|
MsgBox("Ein Fehler ist aufgetreten" + ex.Message)
|
|
Finally
|
|
dsdata = Nothing
|
|
End Try
|
|
If with_message = True Then MsgBox("Auslesen der Daten erfolgreich beendet.")
|
|
End Sub
|
|
|
|
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
|
|
Dim s As String
|
|
Me.OpenFileDialog1.ShowDialog()
|
|
If Me.OpenFileDialog1.FileName <> "" Then
|
|
Me.txtConnstring.Text = ""
|
|
FileOpen(1, Me.OpenFileDialog1.FileName, OpenMode.Input)
|
|
While Not EOF(1)
|
|
Input(1, s)
|
|
Me.txtConnstring.Text = Me.txtConnstring.Text + s
|
|
End While
|
|
FileClose(1)
|
|
End If
|
|
End Sub
|
|
|
|
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
|
|
Me.OpenFileDialog1.ShowDialog()
|
|
If Me.OpenFileDialog1.FileName <> "" Then Me.txtFilename.Text = Me.OpenFileDialog1.FileName
|
|
End Sub
|
|
|
|
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
|
|
save_data()
|
|
|
|
End Sub
|
|
|
|
Private Sub save_data()
|
|
Dim dsdata As New DataSet
|
|
Dim filename As String = Me.txtFilename.Text
|
|
Dim sql As String = ""
|
|
sql = "Select * from " + Me.TxtTable.Text
|
|
sql = sql & " where " + Me.TxtKeyField.Text
|
|
sql = sql & "="
|
|
If Me.cbstring.Checked = True Then sql = sql & "'"
|
|
sql = sql & Me.TxtKeyValue.Text
|
|
If Me.cbstring.Checked = True Then sql = sql & "'"
|
|
Try
|
|
dsdata.Tables.Clear()
|
|
Dim connection As New SqlConnection
|
|
Dim da As New SqlDataAdapter(sql, connection)
|
|
Dim cb As SqlCommandBuilder = New SqlCommandBuilder(da)
|
|
Dim ds As New DataSet
|
|
Dim fs As New FileStream(filename, FileMode.Open, FileAccess.Read)
|
|
Dim mydata(fs.Length) As Byte
|
|
fs.Read(mydata, 0, fs.Length)
|
|
fs.Close()
|
|
connection.ConnectionString = Me.txtConnstring.Text
|
|
connection.Open()
|
|
da.Fill(ds, "empf")
|
|
Dim myRow As DataRow
|
|
If ds.Tables(0).Rows.Count = 0 Then
|
|
MsgBox("Es wurde kein Daten für den Update selektiert.")
|
|
Else
|
|
If ds.Tables(0).Rows.Count > 1 Then
|
|
MsgBox("Es wurden mehr als 1 Datensatz für den Update selektiert.")
|
|
Else
|
|
Dim i As Integer
|
|
Dim idatafield As Integer = -1
|
|
|
|
For i = 0 To ds.Tables(0).Columns.Count - 1
|
|
If UCase(ds.Tables(0).Columns(i).Caption) = UCase(Me.txtBindDatafeld.Text) Then
|
|
idatafield = i
|
|
End If
|
|
Next
|
|
|
|
myRow = ds.Tables(0).Rows(0)
|
|
myRow.Item(idatafield) = mydata
|
|
da.Update(ds, "empf")
|
|
End If
|
|
End If
|
|
fs = Nothing
|
|
cb = Nothing
|
|
ds = Nothing
|
|
da = Nothing
|
|
connection.Close()
|
|
connection = Nothing
|
|
|
|
Catch ex As Exception
|
|
MsgBox("Es ist ein Fehler aufgetreten." & ex.Message)
|
|
End Try
|
|
MsgBox("Speichern der Daten erfolgreich beendet.")
|
|
End Sub
|
|
|
|
Private Sub MenuItem2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem2.Click
|
|
Me.Close()
|
|
End Sub
|
|
|
|
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
|
|
If args.Length > 1 Then
|
|
If check_args() = False Then Me.Close()
|
|
End If
|
|
check_args()
|
|
End Sub
|
|
|
|
Dim arg_connectionstring As String = ""
|
|
Dim arg_direction As String = ""
|
|
Dim arg_filename As String = ""
|
|
Dim arg_tablename As String = ""
|
|
Dim arg_keyfield As String = ""
|
|
Dim arg_keyvalue As String = ""
|
|
Dim arg_binfield As String = ""
|
|
|
|
Private Function check_args()
|
|
If args.Length < 7 Then Return False
|
|
Dim I As Integer
|
|
For I = 1 To 7
|
|
Select Case UCase(args(I).Substring(1, 2))
|
|
Case "D:"
|
|
arg_direction = args(I).Substring(2, Len(args(I) - 2))
|
|
Case "C:"
|
|
arg_connectionstring = args(I).Substring(2, Len(args(I) - 2))
|
|
Me.txtConnstring.Text = arg_connectionstring
|
|
Case "F:"
|
|
arg_filename = args(I).Substring(2, Len(args(I) - 2))
|
|
Me.txtFilename.Text = arg_filename
|
|
Case "T:"
|
|
arg_tablename = args(I).Substring(2, Len(args(I) - 2))
|
|
Me.TxtTable.Text = arg_tablename
|
|
Case "K:"
|
|
arg_keyfield = args(I).Substring(2, Len(args(I) - 2))
|
|
Me.TxtKeyField.Text = arg_keyfield
|
|
Case "V:"
|
|
arg_keyvalue = args(I).Substring(2, Len(args(I) - 2))
|
|
Me.TxtKeyValue.Text = arg_keyvalue
|
|
Case "B:"
|
|
arg_binfield = args(I).Substring(2, Len(args(I) - 2))
|
|
Me.txtBindDatafeld.Text = arg_binfield
|
|
End Select
|
|
Next
|
|
End Function
|
|
|
|
Private Function Get_Connparam(ByVal No As String) As String
|
|
Dim xmldoc As New XmlDocument
|
|
xmldoc.Load(ApplicationPath() + "connections.xml")
|
|
Return xmldoc.SelectSingleNode("/Configuration/" + No).InnerText
|
|
xmldoc = Nothing
|
|
End Function
|
|
|
|
Public Function ApplicationPath() As String
|
|
Return Path.GetDirectoryName([Assembly].GetEntryAssembly().Location) + "\"
|
|
End Function
|
|
|
|
Dim Batchdata As New DataTable
|
|
Private Sub MenuItem3_Click(sender As Object, e As EventArgs) Handles MenuItem3.Click
|
|
OpenFileDialog1.ShowDialog()
|
|
|
|
If OpenFileDialog1.FileName <> "" Then
|
|
Dim x As New XLSLib.clsXLSLib
|
|
Batchdata = x.Get_Excel(OpenFileDialog1.FileName, True)
|
|
For Each r As DataRow In Me.Batchdata.Rows
|
|
Me.txtConnstring.Text = r("Connectionstring")
|
|
Me.txtFilename.Text = r("OutputDir") + "\" + r("Outputname")
|
|
Me.TxtTable.Text = r("Tabelle")
|
|
Me.TxtKeyField.Text = r("KeyField")
|
|
Me.TxtKeyValue.Text = r("KeyValue")
|
|
Me.txtBindDatafeld.Text = r("bindatafield")
|
|
MsgBox(Me.txtFilename.Text)
|
|
Load_Data(False)
|
|
Next
|
|
End If
|
|
End Sub
|
|
End Class
|