From 68f23abd20e8b3dd92ab265bd9379683fded471f Mon Sep 17 00:00:00 2001 From: patowhiz Date: Fri, 24 Mar 2023 14:59:06 +0300 Subject: [PATCH 1/3] changes --- ClimsoftVer4/ClimsoftVer4/ClimsoftVer4.vbproj | 9 + ClimsoftVer4/ClimsoftVer4/clsDataCall.vb | 35 +-- .../ClimsoftVer4/frmImportQCData.Designer.vb | 192 +++++++++++++ .../ClimsoftVer4/frmImportQCData.resx | 120 +++++++++ ClimsoftVer4/ClimsoftVer4/frmImportQCData.vb | 254 ++++++++++++++++++ ClimsoftVer4/ClimsoftVer4/frmMainMenu.vb | 3 - 6 files changed, 593 insertions(+), 20 deletions(-) create mode 100644 ClimsoftVer4/ClimsoftVer4/frmImportQCData.Designer.vb create mode 100644 ClimsoftVer4/ClimsoftVer4/frmImportQCData.resx create mode 100644 ClimsoftVer4/ClimsoftVer4/frmImportQCData.vb diff --git a/ClimsoftVer4/ClimsoftVer4/ClimsoftVer4.vbproj b/ClimsoftVer4/ClimsoftVer4/ClimsoftVer4.vbproj index e461d0be..2c870ea0 100644 --- a/ClimsoftVer4/ClimsoftVer4/ClimsoftVer4.vbproj +++ b/ClimsoftVer4/ClimsoftVer4/ClimsoftVer4.vbproj @@ -189,6 +189,12 @@ Form + + frmImportQCData.vb + + + Form + frmInventoryChart.vb @@ -908,6 +914,9 @@ frmFormUpload.vb + + frmImportQCData.vb + frmInventoryChart.vb diff --git a/ClimsoftVer4/ClimsoftVer4/clsDataCall.vb b/ClimsoftVer4/ClimsoftVer4/clsDataCall.vb index 6b5ff2ab..2e4d91ba 100644 --- a/ClimsoftVer4/ClimsoftVer4/clsDataCall.vb +++ b/ClimsoftVer4/ClimsoftVer4/clsDataCall.vb @@ -116,20 +116,20 @@ Public Class DataCall SetFilter(clsNewFilter:=clsNewFilter) End Sub - Public Function GetValues() As List(Of String) - Dim lstValues As New List(Of String) - Dim objData As Object + 'Public Function GetValues() As List(Of String) + ' Dim lstValues As New List(Of String) + ' Dim objData As Object - objData = GetDataTable() - For Each entItem In objData - lstValues.Add(CallByName(entItem, dctFields.Keys(0), CallType.Get)) - Next - Return lstValues - End Function + ' objData = GetDataTable() + ' For Each entItem In objData + ' lstValues.Add(CallByName(entItem, dctFields.Keys(0), CallType.Get)) + ' Next + ' Return lstValues + 'End Function - Public Function GetValuesAsString(Optional strSep As String = ",") As String - Return String.Join(strSep, GetValues()) - End Function + 'Public Function GetValuesAsString(Optional strSep As String = ",") As String + ' Return String.Join(strSep, GetValues()) + 'End Function Public Function GetFields() As Dictionary(Of String, List(Of String)) Return dctFields @@ -175,18 +175,19 @@ Public Class DataCall End If End If + 'initialise adapter command objects cmdSelect = New MySql.Data.MySqlClient.MySqlCommand() cmdInsert = New MySql.Data.MySqlClient.MySqlCommand() cmdUpdate = New MySql.Data.MySqlClient.MySqlCommand() cmdDelete = New MySql.Data.MySqlClient.MySqlCommand() + 'get the table schema dtbSchema = GetTableSchema(strTable) - 'Get the field names and parameter placeholders + 'Get distinct field names and construct their parameter placeholders For Each lstFieldNames As List(Of String) In dctFields.Values lstTempFieldNames.AddRange(lstFieldNames) Next - lstTempFieldNames = lstTempFieldNames.Distinct().ToList For Each strName As String In lstTempFieldNames @@ -426,9 +427,9 @@ Public Class DataCall 'TODO This should return the Linq expression that goes in the Select method - Public Function GetSelectLinqExpression() As String - Return "" - End Function + 'Public Function GetSelectLinqExpression() As String + ' Return "" + 'End Function Public Function TableCount(Optional clsAdditionalFilter As TableFilter = Nothing) As Integer Dim iCount As Integer diff --git a/ClimsoftVer4/ClimsoftVer4/frmImportQCData.Designer.vb b/ClimsoftVer4/ClimsoftVer4/frmImportQCData.Designer.vb new file mode 100644 index 00000000..a24bf536 --- /dev/null +++ b/ClimsoftVer4/ClimsoftVer4/frmImportQCData.Designer.vb @@ -0,0 +1,192 @@ + _ +Partial Class frmImportQCData + Inherits System.Windows.Forms.Form + + 'Form overrides dispose to clean up the component list. + _ + Protected Overrides Sub Dispose(ByVal disposing As Boolean) + Try + If disposing AndAlso components IsNot Nothing Then + components.Dispose() + End If + Finally + MyBase.Dispose(disposing) + End Try + End Sub + + 'Required by the Windows Form Designer + Private components As System.ComponentModel.IContainer + + 'NOTE: The following procedure is required by the Windows Form Designer + 'It can be modified using the Windows Form Designer. + 'Do not modify it using the code editor. + _ + Private Sub InitializeComponent() + Me.txtFilePath = New System.Windows.Forms.TextBox() + Me.lblSelectFile = New System.Windows.Forms.Label() + Me.btnBrowse = New System.Windows.Forms.Button() + Me.rtfSummaryReport = New System.Windows.Forms.RichTextBox() + Me.dataGridFileContents = New System.Windows.Forms.DataGridView() + Me.btnSave = New System.Windows.Forms.Button() + Me.btnClose = New System.Windows.Forms.Button() + Me.btnHelp = New System.Windows.Forms.Button() + Me.grpFileContents = New System.Windows.Forms.GroupBox() + Me.GroupBox1 = New System.Windows.Forms.GroupBox() + Me.GroupBox2 = New System.Windows.Forms.GroupBox() + Me.RichTextBox1 = New System.Windows.Forms.RichTextBox() + CType(Me.dataGridFileContents, System.ComponentModel.ISupportInitialize).BeginInit() + Me.grpFileContents.SuspendLayout() + Me.GroupBox1.SuspendLayout() + Me.GroupBox2.SuspendLayout() + Me.SuspendLayout() + ' + 'txtFilePath + ' + Me.txtFilePath.Location = New System.Drawing.Point(116, 7) + Me.txtFilePath.Name = "txtFilePath" + Me.txtFilePath.Size = New System.Drawing.Size(320, 20) + Me.txtFilePath.TabIndex = 2 + ' + 'lblSelectFile + ' + Me.lblSelectFile.AutoSize = True + Me.lblSelectFile.Location = New System.Drawing.Point(12, 14) + Me.lblSelectFile.Name = "lblSelectFile" + Me.lblSelectFile.Size = New System.Drawing.Size(59, 13) + Me.lblSelectFile.TabIndex = 3 + Me.lblSelectFile.Text = "Select File:" + ' + 'btnBrowse + ' + Me.btnBrowse.Location = New System.Drawing.Point(442, 5) + Me.btnBrowse.Name = "btnBrowse" + Me.btnBrowse.Size = New System.Drawing.Size(75, 23) + Me.btnBrowse.TabIndex = 4 + Me.btnBrowse.Text = "Browse" + Me.btnBrowse.UseVisualStyleBackColor = True + ' + 'rtfSummaryReport + ' + Me.rtfSummaryReport.Dock = System.Windows.Forms.DockStyle.Fill + Me.rtfSummaryReport.Location = New System.Drawing.Point(3, 16) + Me.rtfSummaryReport.Name = "rtfSummaryReport" + Me.rtfSummaryReport.Size = New System.Drawing.Size(282, 172) + Me.rtfSummaryReport.TabIndex = 5 + Me.rtfSummaryReport.Text = "" + ' + 'dataGridFileContents + ' + Me.dataGridFileContents.AllowUserToAddRows = False + Me.dataGridFileContents.AllowUserToDeleteRows = False + Me.dataGridFileContents.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize + Me.dataGridFileContents.Dock = System.Windows.Forms.DockStyle.Fill + Me.dataGridFileContents.Location = New System.Drawing.Point(3, 16) + Me.dataGridFileContents.Name = "dataGridFileContents" + Me.dataGridFileContents.ReadOnly = True + Me.dataGridFileContents.Size = New System.Drawing.Size(504, 506) + Me.dataGridFileContents.TabIndex = 6 + ' + 'btnSave + ' + Me.btnSave.Location = New System.Drawing.Point(12, 583) + Me.btnSave.Name = "btnSave" + Me.btnSave.Size = New System.Drawing.Size(75, 23) + Me.btnSave.TabIndex = 7 + Me.btnSave.Text = "Save" + Me.btnSave.UseVisualStyleBackColor = True + ' + 'btnClose + ' + Me.btnClose.Location = New System.Drawing.Point(93, 583) + Me.btnClose.Name = "btnClose" + Me.btnClose.Size = New System.Drawing.Size(75, 23) + Me.btnClose.TabIndex = 8 + Me.btnClose.Text = "Close" + Me.btnClose.UseVisualStyleBackColor = True + ' + 'btnHelp + ' + Me.btnHelp.Location = New System.Drawing.Point(186, 583) + Me.btnHelp.Name = "btnHelp" + Me.btnHelp.Size = New System.Drawing.Size(75, 23) + Me.btnHelp.TabIndex = 9 + Me.btnHelp.Text = "Help" + Me.btnHelp.UseVisualStyleBackColor = True + ' + 'grpFileContents + ' + Me.grpFileContents.Controls.Add(Me.dataGridFileContents) + Me.grpFileContents.Location = New System.Drawing.Point(7, 46) + Me.grpFileContents.Name = "grpFileContents" + Me.grpFileContents.Size = New System.Drawing.Size(510, 525) + Me.grpFileContents.TabIndex = 11 + Me.grpFileContents.TabStop = False + Me.grpFileContents.Text = "Slected File Contents" + ' + 'GroupBox1 + ' + Me.GroupBox1.Controls.Add(Me.rtfSummaryReport) + Me.GroupBox1.Location = New System.Drawing.Point(523, 46) + Me.GroupBox1.Name = "GroupBox1" + Me.GroupBox1.Size = New System.Drawing.Size(288, 191) + Me.GroupBox1.TabIndex = 12 + Me.GroupBox1.TabStop = False + Me.GroupBox1.Text = "Summary Report" + ' + 'GroupBox2 + ' + Me.GroupBox2.Controls.Add(Me.RichTextBox1) + Me.GroupBox2.Location = New System.Drawing.Point(523, 253) + Me.GroupBox2.Name = "GroupBox2" + Me.GroupBox2.Size = New System.Drawing.Size(288, 318) + Me.GroupBox2.TabIndex = 13 + Me.GroupBox2.TabStop = False + Me.GroupBox2.Text = "Detailed Report" + ' + 'RichTextBox1 + ' + Me.RichTextBox1.Dock = System.Windows.Forms.DockStyle.Fill + Me.RichTextBox1.Location = New System.Drawing.Point(3, 16) + Me.RichTextBox1.Name = "RichTextBox1" + Me.RichTextBox1.Size = New System.Drawing.Size(282, 299) + Me.RichTextBox1.TabIndex = 5 + Me.RichTextBox1.Text = "" + ' + 'frmImportQCData + ' + Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) + Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font + Me.ClientSize = New System.Drawing.Size(819, 612) + Me.Controls.Add(Me.GroupBox2) + Me.Controls.Add(Me.GroupBox1) + Me.Controls.Add(Me.grpFileContents) + Me.Controls.Add(Me.btnHelp) + Me.Controls.Add(Me.btnClose) + Me.Controls.Add(Me.btnSave) + Me.Controls.Add(Me.btnBrowse) + Me.Controls.Add(Me.lblSelectFile) + Me.Controls.Add(Me.txtFilePath) + Me.Name = "frmImportQCData" + Me.Text = "Import R-Instat Quality Controlled Data" + CType(Me.dataGridFileContents, System.ComponentModel.ISupportInitialize).EndInit() + Me.grpFileContents.ResumeLayout(False) + Me.GroupBox1.ResumeLayout(False) + Me.GroupBox2.ResumeLayout(False) + Me.ResumeLayout(False) + Me.PerformLayout() + + End Sub + + Friend WithEvents txtFilePath As TextBox + Friend WithEvents lblSelectFile As Label + Friend WithEvents btnBrowse As Button + Friend WithEvents rtfSummaryReport As RichTextBox + Friend WithEvents dataGridFileContents As DataGridView + Friend WithEvents btnSave As Button + Friend WithEvents btnClose As Button + Friend WithEvents btnHelp As Button + Friend WithEvents grpFileContents As GroupBox + Friend WithEvents GroupBox1 As GroupBox + Friend WithEvents GroupBox2 As GroupBox + Friend WithEvents RichTextBox1 As RichTextBox +End Class diff --git a/ClimsoftVer4/ClimsoftVer4/frmImportQCData.resx b/ClimsoftVer4/ClimsoftVer4/frmImportQCData.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/ClimsoftVer4/ClimsoftVer4/frmImportQCData.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/ClimsoftVer4/ClimsoftVer4/frmImportQCData.vb b/ClimsoftVer4/ClimsoftVer4/frmImportQCData.vb new file mode 100644 index 00000000..c56aeb09 --- /dev/null +++ b/ClimsoftVer4/ClimsoftVer4/frmImportQCData.vb @@ -0,0 +1,254 @@ +Imports System.Windows.Forms.DataVisualization.Charting + +Public Class frmImportQCData + + 'Private dtbQCFileData As DataTable + + Private Sub frmImportQCData_Load(sender As Object, e As EventArgs) Handles MyBase.Load + + End Sub + + Private Sub fillDataGridView(dtbQCData As DataTable) + dataGridFileContents.DataSource = dtbQCData + 'dataGridFileContents.Refresh() + End Sub + + + Private Sub GetQCFileDataFromCSV(strFilePath As String) + + Dim dtbQCData As DataTable = GetQCFileDataTableDefinition() + + Using fileReader As New FileIO.TextFieldParser(strFilePath) + fileReader.TextFieldType = FileIO.FieldType.Delimited + fileReader.SetDelimiters(",") + + + 'read the first line, get usable column names from it's fields + 'dictionary of; mapped datatable column name and mapped field index + Dim dctUsableColNames As Dictionary(Of String, Integer) = ValidateAndGetUsableFileColumns(fileReader.ReadFields(), dtbQCData) + + 'if no usable column names then just exit + If dctUsableColNames Is Nothing Then + Exit Sub + End If + + Dim currentRow As String() + While Not fileReader.EndOfData + Try + 'get data table row definitial + Dim dataRow As DataRow = dtbQCData.NewRow + 'get file row fields + currentRow = fileReader.ReadFields() + + 'loop through usable columns while using the mapped field index to get the file field value from the file row + 'add the file field values in the data row + For Each usableCol As KeyValuePair(Of String, Integer) In dctUsableColNames + Dim fileFieldValue As String = currentRow(usableCol.Value) + + 'todo. validate values + Select Case usableCol.Key + Case "station_id" + dataRow.SetField(Of String)(usableCol.Key, fileFieldValue) + Case "element_id" + dataRow.SetField(Of Integer)(usableCol.Key, Integer.Parse(fileFieldValue)) + Case "acquisition_type" + dataRow.SetField(Of Integer)(usableCol.Key, Integer.Parse(fileFieldValue)) + Case "date_time" + dataRow.SetField(Of String)(usableCol.Key, fileFieldValue) + Case "qc_log" + dataRow.SetField(Of String)(usableCol.Key, fileFieldValue) + Case "flag" + dataRow.SetField(Of String)(usableCol.Key, fileFieldValue) + Case "value" + dataRow.SetField(Of Integer)(usableCol.Key, Integer.Parse(fileFieldValue)) + Case Else + Continue For + End Select + Next + + 'dataRow.RowError + + dtbQCData.Rows.Add(dataRow) + + Catch ex As FileIO.MalformedLineException + MsgBox("Line " & ex.Message & " is not valid and will be skipped.") + Catch ex As Exception + MsgBox("Error " & ex.Message & ". Exiting.") + End Try + End While + End Using + End Sub + + Private Function GetQCFileDataTableDefinition() As DataTable + Dim dtbQCFileData As New DataTable + + 'data record identifier values + '-------------------------------------------- + dtbQCFileData.Columns.Add("station_id", GetType(String)) + dtbQCFileData.Columns.Add("element_id", GetType(Integer)) + dtbQCFileData.Columns.Add("acquisition_type", GetType(Integer)) + dtbQCFileData.Columns.Add("date_time", GetType(Date)) + '-------------------------------------------- + + 'expected data record changes + '-------------------------------------------- + dtbQCFileData.Columns.Add("qc_log", GetType(String)) + dtbQCFileData.Columns.Add("flag", GetType(String)) + dtbQCFileData.Columns.Add("value", GetType(String)) + '-------------------------------------------- + + 'PS note, intentionally + 'ignore capturedBy, dataForm because they are entered by a climsoft application + 'ignore period, obsLevel because no QC changes is expected and they don't define the record + + Return dtbQCFileData + + End Function + + + Private Function ValidateAndGetUsableFileColumns(arrFileColNames As String(), dtb As DataTable) As Dictionary(Of String, Integer) + Dim dctUsableColNames As New Dictionary(Of String, Integer) + + For fileColNameIndex As Integer = 0 To fileColNameIndex < arrFileColNames.Length + For Each column As DataColumn In dtb.Columns + If column.ColumnName = arrFileColNames(fileColNameIndex) Then + 'column names from the file should be unique + If dctUsableColNames.ContainsKey(column.ColumnName) Then + MsgBox("Duplicate " & column.ColumnName & " detected") + Else + dctUsableColNames.Add(column.ColumnName, fileColNameIndex) + End If + End If + Next + Next + + 'validate column number + If dctUsableColNames.Count <> dtb.Columns.Count Then + MsgBox("Minimum of " & dtb.Columns.Count & " columns expected") + Return Nothing + End If + + + Return dctUsableColNames + End Function + + + + Private Sub SaveQCData(dtbQCData As DataTable) + Dim strSql As String + + + Dim strStationId As String + Dim iElementId As Integer + Dim iAcquisitionType As Integer + Dim dtObsDateTime As Date + Dim strQCLog As String + Dim strFlag As String + Dim strValue As String + + Dim iCurrentQCStatus As Integer + Dim strCurrentFlag As String + Dim strCurrentValue As String + Dim strCurrentPeriod As String + Dim strCurrentCapturedBy As String + Dim strCurrentTempUnits As String + Dim strCurrentPrecipUnits As String + Dim strCurrentCloudHeightUnits As String + Dim strCurrentVisUnits As String + Dim bRecordChanged As Integer + + For Each row As DataRow In dtbQCData.Rows + + strStationId = row.Field(Of String)("station_id") + iElementId = row.Field(Of Integer)("element_id") + iAcquisitionType = row.Field(Of String)("acquisition_type") + dtObsDateTime = row.Field(Of Date)("date_time") + strQCLog = row.Field(Of String)("qc_log") + strFlag = row.Field(Of String)("flag") + strValue = row.Field(Of String)("value") + + 'get the record ordered by QC status. Important to order by QC status + strSql = "SELECT * FROM observationInitial WHERE recordedFrom=@stationId AND describedBy=@elementId AND obsDatetime=@obsDatetime AND qcStatus=@qcStatus AND acquisitionType=@acquisitiontype ORDER BY qcStatus" + Using cmd As New MySql.Data.MySqlClient.MySqlCommand(strSql, clsDataConnection.GetOpenedConnection) + cmd.Parameters.AddWithValue("@stationId", strStationId) + cmd.Parameters.AddWithValue("@elementId", iElementId) + cmd.Parameters.AddWithValue("@obsDatetime", dtObsDateTime) + cmd.Parameters.AddWithValue("@acquisitiontype", iAcquisitionType) + + Using reader As MySql.Data.MySqlClient.MySqlDataReader = cmd.ExecuteReader() + If reader.HasRows Then + 'go through the records in initial and get it's last updated qc status + While reader.Read() + iCurrentQCStatus = reader.GetInt32("qcStatus") + strCurrentValue = If(String.IsNullOrEmpty(reader.GetString("obsValue")), "", reader.GetString("obsValue")) + strCurrentFlag = If(String.IsNullOrEmpty(reader.GetString("flag")), "", reader.GetString("flag")) + bRecordChanged = strCurrentValue <> strValue OrElse strCurrentFlag <> strFlag + End While + Else + Continue For + End If + + End Using + End Using + + Dim clsDataCall As New DataCall + clsDataCall.SetTableName("observationInitial") + clsDataCall.SetKeyFields({"recordedFrom", "describedBy", "obsDatetime", "qcStatus", "acquisitionType"}) + 'clsDataCall.Set + + + Dim da As New MySql.Data.MySqlClient.MySqlDataAdapter + Dim dtb As New DataTable + + Dim cmdSelect As New MySql.Data.MySqlClient.MySqlCommand() + Dim cmdInsert As New MySql.Data.MySqlClient.MySqlCommand() + Dim cmdUpdate As New MySql.Data.MySqlClient.MySqlCommand() + + cmdSelect.Connection = clsDataConnection.GetOpenedConnection + 'important to order by QC status + cmdSelect.CommandText = "SELECT * FROM observationInitial WHERE recordedFrom=@stationId AND describedBy=@elementId AND obsDatetime=@obsDatetime AND qcStatus=@qcStatus AND acquisitionType=@acquisitiontype ORDER BY qcStatus" + + cmdInsert.Connection = clsDataConnection.GetOpenedConnection + cmdInsert.CommandText = "INSERT INTO observationInitial(recordedFrom,describedBy,obsDatetime,obsLevel,obsValue,flag,period,qcStatus,acquisitionType,capturedBy,dataForm,temperatureUnits,precipitationUnits,cloudHeightUnits,visUnits) " & + "VALUES (@stationId,@elemCode,@obsDatetime,@obsLevel,@obsVal,@obsFlag,@obsPeriod,@qcStatus,@acquisitiontype,@capturedBy,@dataForm,@temperatureUnits,@precipUnits,@cloudHeightUnits,@visUnits)" + + cmdUpdate.Connection = clsDataConnection.GetOpenedConnection + cmdUpdate.CommandText = "UPDATE observationInitial SET obsValue=@obsVal,flag=@obsFlag,period=@obsPeriod,qcStatus=@qcStatus,capturedBy=@capturedBy " & + " WHERE recordedFrom=@stationId And describedBy=@elementId AND acquisitionType=@acquisitiontype AND obsDatetime=@obsDatetime AND qcStatus=@qcStatus" + + + da.SelectCommand = cmdSelect + da.InsertCommand = cmdInsert + da.UpdateCommand = cmdUpdate + + + + da.Fill(dtb) + + Dim strDatabaseAction As String + strDatabaseAction = "" + + If iCurrentQCStatus = 0 AndAlso Not bRecordChanged Then + 'update the record with qc status 1 and it's qc log if it's there + strDatabaseAction = "update" + ElseIf iCurrentQCStatus = 1 AndAlso Not bRecordChanged Then + 'do nothing + ElseIf iCurrentQCStatus = 2 AndAlso Not bRecordChanged Then + 'do nothing + ElseIf iCurrentQCStatus = 1 AndAlso bRecordChanged Then + 'add new record with QC status 2 and the new updated values + strDatabaseAction = "insert" + ElseIf iCurrentQCStatus = 2 AndAlso bRecordChanged Then + 'update the record with qc status 2 and the new updated values + strDatabaseAction = "update" + End If + + + + + Next + End Sub + + + +End Class \ No newline at end of file diff --git a/ClimsoftVer4/ClimsoftVer4/frmMainMenu.vb b/ClimsoftVer4/ClimsoftVer4/frmMainMenu.vb index 1b36f367..d144f727 100644 --- a/ClimsoftVer4/ClimsoftVer4/frmMainMenu.vb +++ b/ClimsoftVer4/ClimsoftVer4/frmMainMenu.vb @@ -14,9 +14,6 @@ ' You should have received a copy of the GNU General Public License ' along with this program. If not, see . -Imports ClimsoftVer4.Translations - - Public Class frmMainMenu Public HTMLHelp As New clsHelp From b14b61654f271191208a9b88ba869e7ecdf7fd8a Mon Sep 17 00:00:00 2001 From: patowhiz Date: Sat, 25 Mar 2023 08:52:05 +0300 Subject: [PATCH 2/3] more changes --- ClimsoftVer4/ClimsoftVer4/clsDataCall.vb | 278 ++++++------------ ClimsoftVer4/ClimsoftVer4/clsTableFilter.vb | 62 ++-- .../ClimsoftVer4/frmImportQCData.Designer.vb | 14 + ClimsoftVer4/ClimsoftVer4/frmImportQCData.vb | 156 +++++----- ClimsoftVer4/ClimsoftVer4/ucrBaseDataLink.vb | 8 +- ClimsoftVer4/ClimsoftVer4/ucrNavigation.vb | 3 +- 6 files changed, 208 insertions(+), 313 deletions(-) diff --git a/ClimsoftVer4/ClimsoftVer4/clsDataCall.vb b/ClimsoftVer4/ClimsoftVer4/clsDataCall.vb index 2e4d91ba..90ecd0c3 100644 --- a/ClimsoftVer4/ClimsoftVer4/clsDataCall.vb +++ b/ClimsoftVer4/ClimsoftVer4/clsDataCall.vb @@ -13,30 +13,36 @@ ' ' You should have received a copy of the GNU General Public License ' along with this program. If not, see . +Imports MySql.Data.MySqlClient + Public Class DataCall 'Data Adapater to retrieve data from the database Public da As New MySql.Data.MySqlClient.MySqlDataAdapter - Private strTable As String - ' The fields in the table which the values will be from - ' The keys are the names of fields in the data base - ' The values are how the field should be displayed to the user - Private dctFields As Dictionary(Of String, List(Of String)) + Private strTableName As String + + 'holds field names of the database table which the values will be from + 'keys are how the fields should be added in the datatable + 'values are the names of fields in the database + 'todo. change this to a normal list at this level, this structure won't support inserts, update and deletes + Private dctFieldNames As Dictionary(Of String, List(Of String)) + 'fields that will be used for select, insert, update and delete commands Private lstKeyFieldNames As New List(Of String) - 'Private objFields As Object = New Dynamic.ExpandoObject + Private lstOrderByFieldNames As New List(Of String) + Private strSortOrder As String = "" - ' A TableFilter object which defines the rows in the table the values will be from + 'defines the select filter statement Private clsFilter As TableFilter Public Function Clone() As DataCall Dim clsNewDataCall As New DataCall clsNewDataCall.SetDataAdapter(DirectCast(DirectCast(da, ICloneable).Clone(), MySql.Data.MySqlClient.MySqlDataAdapter)) - clsNewDataCall.SetTableName(strTable) - clsNewDataCall.SetFields(ClsCloneFunctions.GetClonedDict(dctFields)) + clsNewDataCall.SetTableName(strTableName) + clsNewDataCall.SetFields(ClsCloneFunctions.GetClonedDict(dctFieldNames)) clsNewDataCall.SetKeyFields(ClsCloneFunctions.GetClonedList(lstKeyFieldNames)) clsNewDataCall.SetFilter(clsFilter.Clone()) @@ -48,15 +54,15 @@ Public Class DataCall End Sub Public Sub SetTableName(strNewTable As String) - strTable = strNewTable + strTableName = strNewTable End Sub Public Function GetTableName() As String - Return strTable + Return strTableName End Function Public Sub SetFields(dctNewFields As Dictionary(Of String, List(Of String))) - dctFields = dctNewFields + dctFieldNames = dctNewFields End Sub Public Sub SetFields(iEnumerableNewFields As IEnumerable(Of String)) @@ -67,28 +73,25 @@ Public Class DataCall SetFields(dctNewFields) End Sub - Public Sub SetField(strNewField As String) - SetFields({strNewField}) - End Sub - Public Sub AddField(strNewField As String) - If dctFields Is Nothing Then + If dctFieldNames Is Nothing Then SetFields(New Dictionary(Of String, List(Of String))) End If - dctFields.Add(strNewField, New List(Of String)({strNewField})) + dctFieldNames.Add(strNewField, New List(Of String)({strNewField})) End Sub - Public Sub SetKeyFields(iEnumerableNewKeyFields As IEnumerable(Of String)) - lstKeyFieldNames = iEnumerableNewKeyFields.ToList() + Public Sub SetKeyFields(enumerableNewKeyFields As IEnumerable(Of String)) + lstKeyFieldNames = enumerableNewKeyFields.ToList() End Sub Public Sub AddKeyField(strNewKeyField As String) lstKeyFieldNames.Add(strNewKeyField) End Sub - Public Sub SetTableNameAndFields(strNewTable As String, dctNewFields As Dictionary(Of String, List(Of String))) - SetTableName(strNewTable) - SetFields(dctNewFields) + Public Sub SetOrderByFields(enumerableNewFields As IEnumerable(Of String), Optional strNewSortOrder As String = "") + lstOrderByFieldNames = enumerableNewFields.ToList() + 'ASC or DESC or "" + strSortOrder = strNewSortOrder End Sub Public Sub SetTableNameAndFields(strNewTable As String, lstNewFields As IEnumerable(Of String)) @@ -96,11 +99,6 @@ Public Class DataCall SetFields(lstNewFields) End Sub - Public Sub SetTableNameAndField(strNewTable As String, strNewField As String) - SetTableName(strNewTable) - SetField(strNewField) - End Sub - Public Function GetFilter() As TableFilter Return clsFilter End Function @@ -116,55 +114,34 @@ Public Class DataCall SetFilter(clsNewFilter:=clsNewFilter) End Sub - 'Public Function GetValues() As List(Of String) - ' Dim lstValues As New List(Of String) - ' Dim objData As Object - - ' objData = GetDataTable() - ' For Each entItem In objData - ' lstValues.Add(CallByName(entItem, dctFields.Keys(0), CallType.Get)) - ' Next - ' Return lstValues - 'End Function - - 'Public Function GetValuesAsString(Optional strSep As String = ",") As String - ' Return String.Join(strSep, GetValues()) - 'End Function - Public Function GetFields() As Dictionary(Of String, List(Of String)) - Return dctFields - End Function - - Public Function GetField() As String - If dctFields.Count = 1 Then - Return dctFields.First.Key - Else - Return "" - End If + Return dctFieldNames End Function Private Sub UpdateDataAdapter(Optional clsAdditionalFilter As TableFilter = Nothing) - Dim clsCurrentFilter As TableFilter - Dim strSqlFieldNames As String - Dim strSqlFieldParameters As String - Dim cmdSelect As MySql.Data.MySqlClient.MySqlCommand - Dim strSelectCommand As String - Dim strKeysWhereCommand As String - Dim cmdInsert As MySql.Data.MySqlClient.MySqlCommand - Dim strInsertCommand As String - Dim cmdUpdate As MySql.Data.MySqlClient.MySqlCommand - Dim strUpdateCommand As String - Dim strUpdateSetCommand As String - Dim cmdDelete As MySql.Data.MySqlClient.MySqlCommand - Dim strDeleteCommand As String - Dim lstTempFieldNames As New List(Of String) - Dim lstTempFieldParameters As New List(Of String) - Dim dtbSchema As DataTable - Dim type As MySql.Data.MySqlClient.MySqlDbType - Dim iSize As Integer - Dim parameterPlaceHolder As String + Try + Dim clsCurrentFilter As TableFilter + Dim strSqlFieldNames As String + Dim strSqlFieldParameters As String + Dim cmdSelect As New MySqlCommand + Dim strSelectCommand As String + Dim strUpdateAndDeleteConditionsParams As String + Dim cmdInsert As New MySqlCommand + Dim strInsertCommand As String + Dim cmdUpdate As New MySqlCommand + Dim strUpdateCommand As String + Dim strUpdateSetCommand As String + Dim cmdDelete As New MySqlCommand + Dim strDeleteCommand As String + Dim lstTempFieldNames As New List(Of String) + Dim lstTempFieldParameters As New List(Of String) + Dim dtbSchema As DataTable + Dim type As MySqlDbType + Dim iSize As Integer + Dim parameterPlaceHolder As String + If IsNothing(clsAdditionalFilter) Then clsCurrentFilter = clsFilter Else @@ -175,24 +152,19 @@ Public Class DataCall End If End If - 'initialise adapter command objects - cmdSelect = New MySql.Data.MySqlClient.MySqlCommand() - cmdInsert = New MySql.Data.MySqlClient.MySqlCommand() - cmdUpdate = New MySql.Data.MySqlClient.MySqlCommand() - cmdDelete = New MySql.Data.MySqlClient.MySqlCommand() 'get the table schema - dtbSchema = GetTableSchema(strTable) + dtbSchema = GetTableSchema(strTableName) 'Get distinct field names and construct their parameter placeholders - For Each lstFieldNames As List(Of String) In dctFields.Values + For Each lstFieldNames As List(Of String) In dctFieldNames.Values lstTempFieldNames.AddRange(lstFieldNames) Next lstTempFieldNames = lstTempFieldNames.Distinct().ToList For Each strName As String In lstTempFieldNames - type = GetFieldMySqlDbType(strName, dtbSchema) + Type = GetFieldMySqlDbType(strName, dtbSchema) iSize = GetFieldMySqlDbLength(strName, dtbSchema) parameterPlaceHolder = "@" & strName @@ -200,55 +172,66 @@ Public Class DataCall lstTempFieldParameters.Add(parameterPlaceHolder) 'TODO change the size parameter for dates - cmdInsert.Parameters.Add(parameterPlaceHolder, type, iSize, strName) + cmdInsert.Parameters.Add(parameterPlaceHolder, Type, iSize, strName) Next strSqlFieldNames = String.Join(",", lstTempFieldNames.ToArray) strSqlFieldParameters = String.Join(",", lstTempFieldParameters.ToArray) + 'SELECT statement + '-------------------------------------------- If lstTempFieldNames.Count > 0 Then - strSelectCommand = "SELECT " & strSqlFieldNames & " FROM " & strTable + strSelectCommand = "SELECT " & strSqlFieldNames & " FROM " & strTableName Else - strSelectCommand = "SELECT * FROM " & strTable + strSelectCommand = "SELECT * FROM " & strTableName End If cmdSelect.Connection = clsDataConnection.GetOpenedConnection - cmdSelect.CommandText = strSelectCommand 'To confirm that this is the best approach to creating the paramatised Querie + cmdSelect.CommandText = strSelectCommand da.SelectCommand = cmdSelect If clsCurrentFilter IsNot Nothing Then 'contsruct the filter statement clsCurrentFilter.AddToSqlcommand(cmdSelect) End If + If lstOrderByFieldNames.Count > 0 Then + cmdSelect.CommandText = cmdSelect.CommandText & " ORDER BY " & String.Join(",", lstOrderByFieldNames.ToArray) & " " & strSortOrder + End If + '-------------------------------------------- + + '-------------------------------------------- 'INSERT statement - strInsertCommand = "INSERT INTO " & strTable & " (" & strSqlFieldNames & ") " & "VALUES (" & strSqlFieldParameters & ")" + strInsertCommand = "INSERT INTO " & strTableName & " (" & strSqlFieldNames & ") " & "VALUES (" & strSqlFieldParameters & ")" cmdInsert.Connection = clsDataConnection.GetOpenedConnection - cmdInsert.CommandText = strInsertCommand 'To confirm that this is the best approach to creating the paramatised Querie + cmdInsert.CommandText = strInsertCommand da.InsertCommand = cmdInsert + '-------------------------------------------- 'Where clause parameters for update and delete statements - strKeysWhereCommand = "" + strUpdateAndDeleteConditionsParams = "" For Each strTempKeyField As String In lstKeyFieldNames parameterPlaceHolder = "@_" & strTempKeyField & "_" - If strKeysWhereCommand = "" Then - strKeysWhereCommand = strTempKeyField & " = " & parameterPlaceHolder + If strUpdateAndDeleteConditionsParams = "" Then + strUpdateAndDeleteConditionsParams = strTempKeyField & " = " & parameterPlaceHolder Else - strKeysWhereCommand = strKeysWhereCommand & " AND " & strTempKeyField & " = " & parameterPlaceHolder + strUpdateAndDeleteConditionsParams = strUpdateAndDeleteConditionsParams & " AND " & strTempKeyField & " = " & parameterPlaceHolder End If - Dim paramUpdate As MySql.Data.MySqlClient.MySqlParameter - Dim paramDelete As MySql.Data.MySqlClient.MySqlParameter + Dim paramUpdate As MySqlParameter + Dim paramDelete As MySqlParameter - type = GetFieldMySqlDbType(strTempKeyField, dtbSchema) + Type = GetFieldMySqlDbType(strTempKeyField, dtbSchema) iSize = GetFieldMySqlDbLength(strTempKeyField, dtbSchema) 'TODO change the size parameter for dates - paramUpdate = New MySql.Data.MySqlClient.MySqlParameter(parameterPlaceHolder, type, iSize, strTempKeyField) - paramUpdate.SourceVersion = DataRowVersion.Original + paramUpdate = New MySqlParameter(parameterPlaceHolder, Type, iSize, strTempKeyField) With { + .SourceVersion = DataRowVersion.Original + } cmdUpdate.Parameters.Add(paramUpdate) - paramDelete = New MySql.Data.MySqlClient.MySqlParameter(parameterPlaceHolder, type, iSize, strTempKeyField) - paramDelete.SourceVersion = DataRowVersion.Original + paramDelete = New MySqlParameter(parameterPlaceHolder, Type, iSize, strTempKeyField) With { + .SourceVersion = DataRowVersion.Original + } cmdDelete.Parameters.Add(paramDelete) Next @@ -263,29 +246,27 @@ Public Class DataCall End If - type = GetFieldMySqlDbType(strTempField, dtbSchema) + Type = GetFieldMySqlDbType(strTempField, dtbSchema) iSize = GetFieldMySqlDbLength(strTempField, dtbSchema) 'TODO change the size parameter for dates - cmdUpdate.Parameters.Add(parameterPlaceHolder, type, iSize, strTempField) + cmdUpdate.Parameters.Add(parameterPlaceHolder, Type, iSize, strTempField) Next 'UPDATE statement - strUpdateCommand = "UPDATE " & strTable & " SET " & strUpdateSetCommand & " WHERE " & strKeysWhereCommand + strUpdateCommand = "UPDATE " & strTableName & " SET " & strUpdateSetCommand & " WHERE " & strUpdateAndDeleteConditionsParams cmdUpdate.Connection = clsDataConnection.GetOpenedConnection cmdUpdate.CommandText = strUpdateCommand 'To confirm that this is the best approach to creating the paramatised Querie da.UpdateCommand = cmdUpdate 'DELETE statement - strDeleteCommand = "DELETE FROM " & strTable & " WHERE " & strKeysWhereCommand + strDeleteCommand = "DELETE FROM " & strTableName & " WHERE " & strUpdateAndDeleteConditionsParams cmdDelete.Connection = clsDataConnection.GetOpenedConnection cmdDelete.CommandText = strDeleteCommand 'To confirm that this is the best approach to creating the paramatised Querie da.DeleteCommand = cmdDelete Catch ex As Exception MsgBox("Error : " & ex.Message) - Finally - 'conn.Close() End Try End Sub @@ -302,6 +283,7 @@ Public Class DataCall Return dtb End Function + 'todo. rename to RefreshDatatable() Public Function GetDataTable(Optional clsAdditionalFilter As TableFilter = Nothing) As DataTable Dim dtb As DataTable Dim lstFields As List(Of String) @@ -310,8 +292,8 @@ Public Class DataCall dtb = GetSourceDataTable(clsAdditionalFilter) If dtb.Columns.Count > 0 Then - For Each strFieldDisplay As String In dctFields.Keys - lstFields = dctFields.Item(strFieldDisplay) + For Each strFieldDisplay As String In dctFieldNames.Keys + lstFields = dctFieldNames.Item(strFieldDisplay) 'if field = 1 just rename the database column name, if not create a sigle column from the fields and combine the values into the single column If lstFields.Count = 1 Then 'TODO Probably create the Display column if it does not exist? @@ -337,6 +319,8 @@ Public Class DataCall Return dtb End Function + 'todo. datacall should not accept a data table that it doesn't know it's definitions + 'this parameter is a potential logical bug Public Function Save(dtb As DataTable) As Boolean Try da.Update(dtb) @@ -347,90 +331,6 @@ Public Class DataCall End Try End Function - 'TODO. Delete this function later - 'Private Function GetDataTableOLD(Optional clsAdditionalFilter As TableFilter = Nothing) As DataTable - ' Dim objData As Object - ' Dim dtbFields As DataTable - - ' objData = GetDataObject(clsAdditionalFilter) - ' dtbFields = New DataTable() - ' If Not dctFields Is Nothing Then - ' For Each strFieldDisplay As String In dctFields.Keys - ' dtbFields.Columns.Add(strFieldDisplay, GetType(String)) - ' Next - ' If objData IsNot Nothing Then - ' For Each Item As Object In objData - ' dtbFields.Rows.Add(GetFieldsArray(Item)) - ' Next - ' End If - ' End If - ' Return dtbFields - 'End Function - - 'TODO. Delete this fucntion - 'Private Function GetFieldsArray(Item As Object, Optional strSep As String = " ") As Object() - ' Dim objFields As New List(Of Object) - ' Dim lstFields As List(Of String) - ' Dim lstCombine As List(Of String) - - ' If Item IsNot Nothing Then - ' For Each strFieldDisplay As String In dctFields.Keys - ' lstFields = dctFields(strFieldDisplay) - ' If lstFields.Count = 1 Then - ' objFields.Add(CallByName(Item, lstFields(0), CallType.Get)) - ' Else - ' lstCombine = New List(Of String) - ' For Each strField In lstFields - ' lstCombine.Add(CallByName(Item, strField, CallType.Get)) - ' Next - ' objFields.Add(String.Join(strSep, lstCombine)) - ' End If - ' Next - ' Return objFields.ToArray() - ' Else - ' Return Nothing - ' End If - 'End Function - - 'TODO. Delete this function - 'Private Function GetDataObject(Optional clsAdditionalFilter As TableFilter = Nothing) As Object - ' Dim clsCurrentFilter As TableFilter - - ' 'TODO. This code is repeated somewhere else. Push it to a function - ' If Not IsNothing(clsAdditionalFilter) Then - ' If IsNothing(clsFilter) Then - ' clsCurrentFilter = clsAdditionalFilter - ' Else - ' clsCurrentFilter = New TableFilter(clsFilter, clsAdditionalFilter) - ' End If - ' Else - ' clsCurrentFilter = clsFilter - ' End If - - ' Try - ' If strTable <> "" Then - ' Dim x = CallByName(clsDataConnection.db, strTable, CallType.Get) - ' Dim y = TryCast(x, IQueryable(Of Object)) - - ' If clsCurrentFilter IsNot Nothing Then - ' y = y.Where(clsCurrentFilter.GetLinqExpression()) - ' End If - ' Return y.ToList() - ' Else - ' MessageBox.Show("Developer error: Table name must be set before data can be retrieved. No data will be returned.", caption:="Developer error") - ' Return Nothing - ' End If - ' Catch ex As Exception - ' Return Nothing - ' End Try - 'End Function - - 'TODO This should return the Linq expression that goes in the Select method - - 'Public Function GetSelectLinqExpression() As String - ' Return "" - 'End Function - Public Function TableCount(Optional clsAdditionalFilter As TableFilter = Nothing) As Integer Dim iCount As Integer Dim clsCurrentFilter As TableFilter @@ -447,7 +347,7 @@ Public Class DataCall End If Try - Using cmd As New MySql.Data.MySqlClient.MySqlCommand("SELECT COUNT(*) AS colnum FROM " & strTable, clsDataConnection.GetOpenedConnection) + Using cmd As New MySql.Data.MySqlClient.MySqlCommand("SELECT COUNT(*) AS colnum FROM " & strTableName, clsDataConnection.GetOpenedConnection) If clsCurrentFilter IsNot Nothing Then clsCurrentFilter.AddToSqlcommand(cmd) End If diff --git a/ClimsoftVer4/ClimsoftVer4/clsTableFilter.vb b/ClimsoftVer4/ClimsoftVer4/clsTableFilter.vb index d427c696..32b3fee0 100644 --- a/ClimsoftVer4/ClimsoftVer4/clsTableFilter.vb +++ b/ClimsoftVer4/ClimsoftVer4/clsTableFilter.vb @@ -119,7 +119,7 @@ Public Class TableFilter End Sub Public Sub New(lstTblFilters As IEnumerable(Of TableFilter), Optional strOperator As String = "AND") - SetFilters(lstTblFilters, strOperator:=strOperator) + SetFilters(lstTblFilters, strFiltersCombination:=strOperator) End Sub Public Sub SetField(strNewField As String) @@ -239,8 +239,8 @@ Public Class TableFilter ''' Will combine the list of filters into one filter ''' ''' - ''' - Public Sub SetFilters(lstTblFilters As IEnumerable(Of TableFilter), Optional strOperator As String = "AND") + ''' + Public Sub SetFilters(lstTblFilters As IEnumerable(Of TableFilter), Optional strFiltersCombination As String = "AND") Dim max As Integer = lstTblFilters.Count - 1 For i As Integer = 0 To max If i = 0 Then @@ -251,7 +251,7 @@ Public Class TableFilter If i <= max - 1 Then Me.SetRightFilter(lstTblFilters(i + 1)) - Me.SetOperator(strOperator) + Me.SetOperator(strFiltersCombination) If i + 1 = max Then Exit For End If @@ -266,33 +266,33 @@ Public Class TableFilter ' Return Function(x) CallByName(x, "stationId", CallType.Get) = "67774010" 'End Function - Public Function GetLinqExpression() As String - Dim strExpression As String - - If bIsCombinedFilter Then - strExpression = clsLeftFilter.GetLinqExpression() & " " & strOperator & " " & clsRightFilter.GetLinqExpression() - Else - strExpression = strField - If bArrayOperator Then - If bValuesFromDataCall Then - strExpression = strExpression & "[" & clsDataCallValues.GetValuesAsString() & "]" - Else - strExpression = strExpression & "[" & String.Join(",", lstValues) & "]" - End If - Else - If bValuesAsString Then - strExpression = strExpression & " " & strOperator & " " & Chr(34) & objValue & Chr(34) - Else - strExpression = strExpression & " " & strOperator & " " & objValue - End If - End If - End If - strExpression = "(" & strExpression & ")" - If Not bIsPositiveCondition Then - strExpression = "not " & strExpression - End If - Return strExpression - End Function + 'Public Function GetLinqExpression() As String + ' Dim strExpression As String + + ' If bIsCombinedFilter Then + ' strExpression = clsLeftFilter.GetLinqExpression() & " " & strOperator & " " & clsRightFilter.GetLinqExpression() + ' Else + ' strExpression = strField + ' If bArrayOperator Then + ' If bValuesFromDataCall Then + ' strExpression = strExpression & "[" & clsDataCallValues.GetValuesAsString() & "]" + ' Else + ' strExpression = strExpression & "[" & String.Join(",", lstValues) & "]" + ' End If + ' Else + ' If bValuesAsString Then + ' strExpression = strExpression & " " & strOperator & " " & Chr(34) & objValue & Chr(34) + ' Else + ' strExpression = strExpression & " " & strOperator & " " & objValue + ' End If + ' End If + ' End If + ' strExpression = "(" & strExpression & ")" + ' If Not bIsPositiveCondition Then + ' strExpression = "not " & strExpression + ' End If + ' Return strExpression + 'End Function Public Function GetSqlExpression() As String Dim strExpression As String diff --git a/ClimsoftVer4/ClimsoftVer4/frmImportQCData.Designer.vb b/ClimsoftVer4/ClimsoftVer4/frmImportQCData.Designer.vb index a24bf536..cba6418b 100644 --- a/ClimsoftVer4/ClimsoftVer4/frmImportQCData.Designer.vb +++ b/ClimsoftVer4/ClimsoftVer4/frmImportQCData.Designer.vb @@ -34,6 +34,7 @@ Partial Class frmImportQCData Me.GroupBox1 = New System.Windows.Forms.GroupBox() Me.GroupBox2 = New System.Windows.Forms.GroupBox() Me.RichTextBox1 = New System.Windows.Forms.RichTextBox() + Me.lblFileSelection = New System.Windows.Forms.Label() CType(Me.dataGridFileContents, System.ComponentModel.ISupportInitialize).BeginInit() Me.grpFileContents.SuspendLayout() Me.GroupBox1.SuspendLayout() @@ -115,6 +116,7 @@ Partial Class frmImportQCData ' 'grpFileContents ' + Me.grpFileContents.Controls.Add(Me.lblFileSelection) Me.grpFileContents.Controls.Add(Me.dataGridFileContents) Me.grpFileContents.Location = New System.Drawing.Point(7, 46) Me.grpFileContents.Name = "grpFileContents" @@ -152,6 +154,16 @@ Partial Class frmImportQCData Me.RichTextBox1.TabIndex = 5 Me.RichTextBox1.Text = "" ' + 'lblFileSelection + ' + Me.lblFileSelection.AutoSize = True + Me.lblFileSelection.Font = New System.Drawing.Font("Microsoft Sans Serif", 18.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) + Me.lblFileSelection.Location = New System.Drawing.Point(119, 143) + Me.lblFileSelection.Name = "lblFileSelection" + Me.lblFileSelection.Size = New System.Drawing.Size(210, 29) + Me.lblFileSelection.TabIndex = 14 + Me.lblFileSelection.Text = "No File Selected" + ' 'frmImportQCData ' Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) @@ -170,6 +182,7 @@ Partial Class frmImportQCData Me.Text = "Import R-Instat Quality Controlled Data" CType(Me.dataGridFileContents, System.ComponentModel.ISupportInitialize).EndInit() Me.grpFileContents.ResumeLayout(False) + Me.grpFileContents.PerformLayout() Me.GroupBox1.ResumeLayout(False) Me.GroupBox2.ResumeLayout(False) Me.ResumeLayout(False) @@ -189,4 +202,5 @@ Partial Class frmImportQCData Friend WithEvents GroupBox1 As GroupBox Friend WithEvents GroupBox2 As GroupBox Friend WithEvents RichTextBox1 As RichTextBox + Friend WithEvents lblFileSelection As Label End Class diff --git a/ClimsoftVer4/ClimsoftVer4/frmImportQCData.vb b/ClimsoftVer4/ClimsoftVer4/frmImportQCData.vb index c56aeb09..21c264aa 100644 --- a/ClimsoftVer4/ClimsoftVer4/frmImportQCData.vb +++ b/ClimsoftVer4/ClimsoftVer4/frmImportQCData.vb @@ -1,28 +1,44 @@ -Imports System.Windows.Forms.DataVisualization.Charting +Imports System.Diagnostics.Eventing +Imports System.Windows.Forms.DataVisualization.Charting Public Class frmImportQCData - 'Private dtbQCFileData As DataTable - Private Sub frmImportQCData_Load(sender As Object, e As EventArgs) Handles MyBase.Load + dataGridFileContents.Visible = False + lblFileSelection.Visible = True + End Sub + Private Sub btnBrowse_Click(sender As Object, e As EventArgs) Handles btnBrowse.Click + Using dlgOpen As New OpenFileDialog + dlgOpen.Filter = "Comma separated files|*.csv" + dlgOpen.Multiselect = False + dlgOpen.Title = "Open Data From File" + If DialogResult.OK = dlgOpen.ShowDialog() Then + txtFilePath.Text = dlgOpen.FileName + Dim dtbQCData As DataTable = GetQCFileDataTableDefinition() + FillQCFileDataFromCSV(dlgOpen.FileName, dtbQCData) + If dtbQCData.Rows.Count = 0 Then + dataGridFileContents.Visible = False + lblFileSelection.Visible = True + Else + dataGridFileContents.Visible = True + dataGridFileContents.DataSource = dtbQCData + End If + End If + End Using End Sub - Private Sub fillDataGridView(dtbQCData As DataTable) + Private Sub FillDataGridView(dtbQCData As DataTable) dataGridFileContents.DataSource = dtbQCData 'dataGridFileContents.Refresh() End Sub - Private Sub GetQCFileDataFromCSV(strFilePath As String) - - Dim dtbQCData As DataTable = GetQCFileDataTableDefinition() - + Private Sub FillQCFileDataFromCSV(strFilePath As String, dtbQCData As DataTable) Using fileReader As New FileIO.TextFieldParser(strFilePath) fileReader.TextFieldType = FileIO.FieldType.Delimited fileReader.SetDelimiters(",") - 'read the first line, get usable column names from it's fields 'dictionary of; mapped datatable column name and mapped field index Dim dctUsableColNames As Dictionary(Of String, Integer) = ValidateAndGetUsableFileColumns(fileReader.ReadFields(), dtbQCData) @@ -77,6 +93,7 @@ Public Class frmImportQCData End Try End While End Using + End Sub Private Function GetQCFileDataTableDefinition() As DataTable @@ -135,13 +152,7 @@ Public Class frmImportQCData Private Sub SaveQCData(dtbQCData As DataTable) - Dim strSql As String - - Dim strStationId As String - Dim iElementId As Integer - Dim iAcquisitionType As Integer - Dim dtObsDateTime As Date Dim strQCLog As String Dim strFlag As String Dim strValue As String @@ -149,106 +160,75 @@ Public Class frmImportQCData Dim iCurrentQCStatus As Integer Dim strCurrentFlag As String Dim strCurrentValue As String - Dim strCurrentPeriod As String - Dim strCurrentCapturedBy As String - Dim strCurrentTempUnits As String - Dim strCurrentPrecipUnits As String - Dim strCurrentCloudHeightUnits As String - Dim strCurrentVisUnits As String Dim bRecordChanged As Integer - For Each row As DataRow In dtbQCData.Rows - - strStationId = row.Field(Of String)("station_id") - iElementId = row.Field(Of Integer)("element_id") - iAcquisitionType = row.Field(Of String)("acquisition_type") - dtObsDateTime = row.Field(Of Date)("date_time") - strQCLog = row.Field(Of String)("qc_log") - strFlag = row.Field(Of String)("flag") - strValue = row.Field(Of String)("value") + Dim dtbInitialData As DataTable + Dim rowInitialToUse As DataRow + Dim clsDataCall As New DataCall + clsDataCall.SetTableName("observationInitial") + clsDataCall.SetFields({"recordedFrom", "describedBy", "obsDatetime", "acquisitionType", "qcStatus", "obsLevel", "period", "capturedBy", "dataForm", "mark", "temperatureUnits", "precipitationUnits", "cloudHeightUnits", "visUnits", "qcTypeLog", "flag", "obsValue"}) + clsDataCall.SetKeyFields({"recordedFrom", "describedBy", "obsDatetime", "acquisitionType", "qcStatus"}) + 'important to order by qc status + clsDataCall.SetOrderByFields({"qcStatus"}) - 'get the record ordered by QC status. Important to order by QC status - strSql = "SELECT * FROM observationInitial WHERE recordedFrom=@stationId AND describedBy=@elementId AND obsDatetime=@obsDatetime AND qcStatus=@qcStatus AND acquisitionType=@acquisitiontype ORDER BY qcStatus" - Using cmd As New MySql.Data.MySqlClient.MySqlCommand(strSql, clsDataConnection.GetOpenedConnection) - cmd.Parameters.AddWithValue("@stationId", strStationId) - cmd.Parameters.AddWithValue("@elementId", iElementId) - cmd.Parameters.AddWithValue("@obsDatetime", dtObsDateTime) - cmd.Parameters.AddWithValue("@acquisitiontype", iAcquisitionType) - - Using reader As MySql.Data.MySqlClient.MySqlDataReader = cmd.ExecuteReader() - If reader.HasRows Then - 'go through the records in initial and get it's last updated qc status - While reader.Read() - iCurrentQCStatus = reader.GetInt32("qcStatus") - strCurrentValue = If(String.IsNullOrEmpty(reader.GetString("obsValue")), "", reader.GetString("obsValue")) - strCurrentFlag = If(String.IsNullOrEmpty(reader.GetString("flag")), "", reader.GetString("flag")) - bRecordChanged = strCurrentValue <> strValue OrElse strCurrentFlag <> strFlag - End While - Else - Continue For - End If - - End Using - End Using - - Dim clsDataCall As New DataCall - clsDataCall.SetTableName("observationInitial") - clsDataCall.SetKeyFields({"recordedFrom", "describedBy", "obsDatetime", "qcStatus", "acquisitionType"}) - 'clsDataCall.Set - - - Dim da As New MySql.Data.MySqlClient.MySqlDataAdapter - Dim dtb As New DataTable - - Dim cmdSelect As New MySql.Data.MySqlClient.MySqlCommand() - Dim cmdInsert As New MySql.Data.MySqlClient.MySqlCommand() - Dim cmdUpdate As New MySql.Data.MySqlClient.MySqlCommand() - - cmdSelect.Connection = clsDataConnection.GetOpenedConnection - 'important to order by QC status - cmdSelect.CommandText = "SELECT * FROM observationInitial WHERE recordedFrom=@stationId AND describedBy=@elementId AND obsDatetime=@obsDatetime AND qcStatus=@qcStatus AND acquisitionType=@acquisitiontype ORDER BY qcStatus" - - cmdInsert.Connection = clsDataConnection.GetOpenedConnection - cmdInsert.CommandText = "INSERT INTO observationInitial(recordedFrom,describedBy,obsDatetime,obsLevel,obsValue,flag,period,qcStatus,acquisitionType,capturedBy,dataForm,temperatureUnits,precipitationUnits,cloudHeightUnits,visUnits) " & - "VALUES (@stationId,@elemCode,@obsDatetime,@obsLevel,@obsVal,@obsFlag,@obsPeriod,@qcStatus,@acquisitiontype,@capturedBy,@dataForm,@temperatureUnits,@precipUnits,@cloudHeightUnits,@visUnits)" + For Each row As DataRow In dtbQCData.Rows - cmdUpdate.Connection = clsDataConnection.GetOpenedConnection - cmdUpdate.CommandText = "UPDATE observationInitial SET obsValue=@obsVal,flag=@obsFlag,period=@obsPeriod,qcStatus=@qcStatus,capturedBy=@capturedBy " & - " WHERE recordedFrom=@stationId And describedBy=@elementId AND acquisitionType=@acquisitiontype AND obsDatetime=@obsDatetime AND qcStatus=@qcStatus" + 'change the data call filter to get new record(s) + clsDataCall.SetFilter(New TableFilter({New TableFilter("recordedFrom", "=", objNewValue:=row.Field(Of String)("station_id")), + New TableFilter("describedBy", "=", objNewValue:=row.Field(Of Integer)("element_id")), + New TableFilter("obsDatetime", "=", objNewValue:=row.Field(Of Date)("date_time")), + New TableFilter("acquisitionType", "=", objNewValue:=row.Field(Of String)("acquisition_type")) + })) + dtbInitialData = clsDataCall.GetDataTable() - da.SelectCommand = cmdSelect - da.InsertCommand = cmdInsert - da.UpdateCommand = cmdUpdate + If dtbInitialData.Rows.Count = 0 Then + 'records not found + Continue For + End If + strQCLog = row.Field(Of String)("qc_log") + strFlag = row.Field(Of String)("flag") + strValue = row.Field(Of String)("value") + 'use the last row + rowInitialToUse = dtbInitialData.Rows(dtbInitialData.Rows.Count - 1) - da.Fill(dtb) + iCurrentQCStatus = rowInitialToUse.Field(Of Integer)("qcStatus") + strCurrentValue = If(IsDBNull(rowInitialToUse.Field(Of String)("obsValue")) OrElse String.IsNullOrEmpty(rowInitialToUse.Field(Of String)("obsValue")), "", rowInitialToUse.Field(Of String)("obsValue")) + strCurrentFlag = If(IsDBNull(rowInitialToUse.Field(Of String)("flag")) OrElse String.IsNullOrEmpty(rowInitialToUse.Field(Of String)("flag")), "", rowInitialToUse.Field(Of String)("flag")) - Dim strDatabaseAction As String - strDatabaseAction = "" + bRecordChanged = strCurrentValue <> strValue OrElse strCurrentFlag <> strFlag If iCurrentQCStatus = 0 AndAlso Not bRecordChanged Then 'update the record with qc status 1 and it's qc log if it's there - strDatabaseAction = "update" + rowInitialToUse.SetField(Of Integer)("qcStatus", 1) ElseIf iCurrentQCStatus = 1 AndAlso Not bRecordChanged Then 'do nothing ElseIf iCurrentQCStatus = 2 AndAlso Not bRecordChanged Then 'do nothing ElseIf iCurrentQCStatus = 1 AndAlso bRecordChanged Then 'add new record with QC status 2 and the new updated values - strDatabaseAction = "insert" + Dim newRow As DataRow = dtbInitialData.NewRow + newRow.ItemArray = rowInitialToUse.ItemArray + newRow.SetField(Of Integer)("qcStatus", 2) + newRow.SetField(Of String)("flag", strFlag) + newRow.SetField(Of String)("obsValue", strValue) + dtbInitialData.Rows.Add(newRow) ElseIf iCurrentQCStatus = 2 AndAlso bRecordChanged Then 'update the record with qc status 2 and the new updated values - strDatabaseAction = "update" + rowInitialToUse.SetField(Of Integer)("qcStatus", 2) + rowInitialToUse.SetField(Of String)("flag", strFlag) + rowInitialToUse.SetField(Of String)("obsValue", strValue) + rowInitialToUse.SetField(Of String)("qcTypeLog", strQCLog) End If + rowInitialToUse.SetField(Of String)("qcTypeLog", strQCLog) - + clsDataCall.Save(dtbInitialData) Next End Sub - End Class \ No newline at end of file diff --git a/ClimsoftVer4/ClimsoftVer4/ucrBaseDataLink.vb b/ClimsoftVer4/ClimsoftVer4/ucrBaseDataLink.vb index b62a2e24..bcf21f16 100644 --- a/ClimsoftVer4/ClimsoftVer4/ucrBaseDataLink.vb +++ b/ClimsoftVer4/ClimsoftVer4/ucrBaseDataLink.vb @@ -71,7 +71,7 @@ Public Class ucrBaseDataLink Public Sub SetField(strNewField As String) CreateDataDefinition() - clsDataDefinition.SetField(strNewField) + clsDataDefinition.SetFields({strNewField}) SetSortByItems() End Sub @@ -109,9 +109,9 @@ Public Class ucrBaseDataLink SetFields(lstNewFields) End Sub - Public Function GetDataField() As String - Return clsDataDefinition.GetField - End Function + 'Public Function GetDataField() As String + ' Return clsDataDefinition.GetField + 'End Function Public Overridable Sub SetFilter(clsNewFilter As TableFilter) CreateDataDefinition() diff --git a/ClimsoftVer4/ClimsoftVer4/ucrNavigation.vb b/ClimsoftVer4/ClimsoftVer4/ucrNavigation.vb index b595c32c..bf3e810a 100644 --- a/ClimsoftVer4/ClimsoftVer4/ucrNavigation.vb +++ b/ClimsoftVer4/ClimsoftVer4/ucrNavigation.vb @@ -556,7 +556,8 @@ Public Class ucrNavigation End If 'fill all the sequencer values from the database - clsSeqDataCall.SetTableNameAndFields(strSequencerTable, dctTableFields) + clsSeqDataCall.SetTableName(strSequencerTable) + clsSeqDataCall.SetFields(dctTableFields) dtbSequencer = clsSeqDataCall.GetDataTable() 'create the select filter statement to be used against the datatable From b0c975fd96f4f2a53081106fb5ad8ea57250960b Mon Sep 17 00:00:00 2001 From: patowhiz Date: Tue, 28 Mar 2023 13:20:23 +0300 Subject: [PATCH 3/3] more changes --- .../ClimsoftVer4/frmImportQCData.Designer.vb | 112 ++++++++---------- ClimsoftVer4/ClimsoftVer4/frmImportQCData.vb | 94 ++++++++++----- ClimsoftVer4/ClimsoftVer4/frmMainMenu.vb | 3 +- 3 files changed, 121 insertions(+), 88 deletions(-) diff --git a/ClimsoftVer4/ClimsoftVer4/frmImportQCData.Designer.vb b/ClimsoftVer4/ClimsoftVer4/frmImportQCData.Designer.vb index cba6418b..5f3a4260 100644 --- a/ClimsoftVer4/ClimsoftVer4/frmImportQCData.Designer.vb +++ b/ClimsoftVer4/ClimsoftVer4/frmImportQCData.Designer.vb @@ -31,37 +31,37 @@ Partial Class frmImportQCData Me.btnClose = New System.Windows.Forms.Button() Me.btnHelp = New System.Windows.Forms.Button() Me.grpFileContents = New System.Windows.Forms.GroupBox() - Me.GroupBox1 = New System.Windows.Forms.GroupBox() - Me.GroupBox2 = New System.Windows.Forms.GroupBox() - Me.RichTextBox1 = New System.Windows.Forms.RichTextBox() Me.lblFileSelection = New System.Windows.Forms.Label() + Me.GroupBox1 = New System.Windows.Forms.GroupBox() CType(Me.dataGridFileContents, System.ComponentModel.ISupportInitialize).BeginInit() Me.grpFileContents.SuspendLayout() Me.GroupBox1.SuspendLayout() - Me.GroupBox2.SuspendLayout() Me.SuspendLayout() ' 'txtFilePath ' - Me.txtFilePath.Location = New System.Drawing.Point(116, 7) + Me.txtFilePath.Location = New System.Drawing.Point(171, 13) + Me.txtFilePath.Margin = New System.Windows.Forms.Padding(4, 5, 4, 5) Me.txtFilePath.Name = "txtFilePath" - Me.txtFilePath.Size = New System.Drawing.Size(320, 20) + Me.txtFilePath.Size = New System.Drawing.Size(478, 26) Me.txtFilePath.TabIndex = 2 ' 'lblSelectFile ' Me.lblSelectFile.AutoSize = True - Me.lblSelectFile.Location = New System.Drawing.Point(12, 14) + Me.lblSelectFile.Location = New System.Drawing.Point(15, 17) + Me.lblSelectFile.Margin = New System.Windows.Forms.Padding(4, 0, 4, 0) Me.lblSelectFile.Name = "lblSelectFile" - Me.lblSelectFile.Size = New System.Drawing.Size(59, 13) + Me.lblSelectFile.Size = New System.Drawing.Size(87, 20) Me.lblSelectFile.TabIndex = 3 Me.lblSelectFile.Text = "Select File:" ' 'btnBrowse ' - Me.btnBrowse.Location = New System.Drawing.Point(442, 5) + Me.btnBrowse.Location = New System.Drawing.Point(660, 8) + Me.btnBrowse.Margin = New System.Windows.Forms.Padding(4, 5, 4, 5) Me.btnBrowse.Name = "btnBrowse" - Me.btnBrowse.Size = New System.Drawing.Size(75, 23) + Me.btnBrowse.Size = New System.Drawing.Size(112, 35) Me.btnBrowse.TabIndex = 4 Me.btnBrowse.Text = "Browse" Me.btnBrowse.UseVisualStyleBackColor = True @@ -69,9 +69,10 @@ Partial Class frmImportQCData 'rtfSummaryReport ' Me.rtfSummaryReport.Dock = System.Windows.Forms.DockStyle.Fill - Me.rtfSummaryReport.Location = New System.Drawing.Point(3, 16) + Me.rtfSummaryReport.Location = New System.Drawing.Point(4, 24) + Me.rtfSummaryReport.Margin = New System.Windows.Forms.Padding(4, 5, 4, 5) Me.rtfSummaryReport.Name = "rtfSummaryReport" - Me.rtfSummaryReport.Size = New System.Drawing.Size(282, 172) + Me.rtfSummaryReport.Size = New System.Drawing.Size(416, 603) Me.rtfSummaryReport.TabIndex = 5 Me.rtfSummaryReport.Text = "" ' @@ -81,35 +82,41 @@ Partial Class frmImportQCData Me.dataGridFileContents.AllowUserToDeleteRows = False Me.dataGridFileContents.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize Me.dataGridFileContents.Dock = System.Windows.Forms.DockStyle.Fill - Me.dataGridFileContents.Location = New System.Drawing.Point(3, 16) + Me.dataGridFileContents.Location = New System.Drawing.Point(4, 24) + Me.dataGridFileContents.Margin = New System.Windows.Forms.Padding(4, 5, 4, 5) Me.dataGridFileContents.Name = "dataGridFileContents" Me.dataGridFileContents.ReadOnly = True - Me.dataGridFileContents.Size = New System.Drawing.Size(504, 506) + Me.dataGridFileContents.RowHeadersVisible = False + Me.dataGridFileContents.RowHeadersWidth = 62 + Me.dataGridFileContents.Size = New System.Drawing.Size(881, 603) Me.dataGridFileContents.TabIndex = 6 ' 'btnSave ' - Me.btnSave.Location = New System.Drawing.Point(12, 583) + Me.btnSave.Location = New System.Drawing.Point(284, 706) + Me.btnSave.Margin = New System.Windows.Forms.Padding(4, 5, 4, 5) Me.btnSave.Name = "btnSave" - Me.btnSave.Size = New System.Drawing.Size(75, 23) + Me.btnSave.Size = New System.Drawing.Size(112, 35) Me.btnSave.TabIndex = 7 Me.btnSave.Text = "Save" Me.btnSave.UseVisualStyleBackColor = True ' 'btnClose ' - Me.btnClose.Location = New System.Drawing.Point(93, 583) + Me.btnClose.Location = New System.Drawing.Point(405, 706) + Me.btnClose.Margin = New System.Windows.Forms.Padding(4, 5, 4, 5) Me.btnClose.Name = "btnClose" - Me.btnClose.Size = New System.Drawing.Size(75, 23) + Me.btnClose.Size = New System.Drawing.Size(112, 35) Me.btnClose.TabIndex = 8 Me.btnClose.Text = "Close" Me.btnClose.UseVisualStyleBackColor = True ' 'btnHelp ' - Me.btnHelp.Location = New System.Drawing.Point(186, 583) + Me.btnHelp.Location = New System.Drawing.Point(531, 706) + Me.btnHelp.Margin = New System.Windows.Forms.Padding(4, 5, 4, 5) Me.btnHelp.Name = "btnHelp" - Me.btnHelp.Size = New System.Drawing.Size(75, 23) + Me.btnHelp.Size = New System.Drawing.Size(112, 35) Me.btnHelp.TabIndex = 9 Me.btnHelp.Text = "Help" Me.btnHelp.UseVisualStyleBackColor = True @@ -118,58 +125,43 @@ Partial Class frmImportQCData ' Me.grpFileContents.Controls.Add(Me.lblFileSelection) Me.grpFileContents.Controls.Add(Me.dataGridFileContents) - Me.grpFileContents.Location = New System.Drawing.Point(7, 46) + Me.grpFileContents.Location = New System.Drawing.Point(9, 71) + Me.grpFileContents.Margin = New System.Windows.Forms.Padding(4, 5, 4, 5) Me.grpFileContents.Name = "grpFileContents" - Me.grpFileContents.Size = New System.Drawing.Size(510, 525) + Me.grpFileContents.Padding = New System.Windows.Forms.Padding(4, 5, 4, 5) + Me.grpFileContents.Size = New System.Drawing.Size(889, 632) Me.grpFileContents.TabIndex = 11 Me.grpFileContents.TabStop = False - Me.grpFileContents.Text = "Slected File Contents" - ' - 'GroupBox1 - ' - Me.GroupBox1.Controls.Add(Me.rtfSummaryReport) - Me.GroupBox1.Location = New System.Drawing.Point(523, 46) - Me.GroupBox1.Name = "GroupBox1" - Me.GroupBox1.Size = New System.Drawing.Size(288, 191) - Me.GroupBox1.TabIndex = 12 - Me.GroupBox1.TabStop = False - Me.GroupBox1.Text = "Summary Report" - ' - 'GroupBox2 - ' - Me.GroupBox2.Controls.Add(Me.RichTextBox1) - Me.GroupBox2.Location = New System.Drawing.Point(523, 253) - Me.GroupBox2.Name = "GroupBox2" - Me.GroupBox2.Size = New System.Drawing.Size(288, 318) - Me.GroupBox2.TabIndex = 13 - Me.GroupBox2.TabStop = False - Me.GroupBox2.Text = "Detailed Report" - ' - 'RichTextBox1 - ' - Me.RichTextBox1.Dock = System.Windows.Forms.DockStyle.Fill - Me.RichTextBox1.Location = New System.Drawing.Point(3, 16) - Me.RichTextBox1.Name = "RichTextBox1" - Me.RichTextBox1.Size = New System.Drawing.Size(282, 299) - Me.RichTextBox1.TabIndex = 5 - Me.RichTextBox1.Text = "" + Me.grpFileContents.Text = "Selected File Contents" ' 'lblFileSelection ' Me.lblFileSelection.AutoSize = True Me.lblFileSelection.Font = New System.Drawing.Font("Microsoft Sans Serif", 18.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) - Me.lblFileSelection.Location = New System.Drawing.Point(119, 143) + Me.lblFileSelection.Location = New System.Drawing.Point(293, 220) + Me.lblFileSelection.Margin = New System.Windows.Forms.Padding(4, 0, 4, 0) Me.lblFileSelection.Name = "lblFileSelection" - Me.lblFileSelection.Size = New System.Drawing.Size(210, 29) + Me.lblFileSelection.Size = New System.Drawing.Size(297, 40) Me.lblFileSelection.TabIndex = 14 Me.lblFileSelection.Text = "No File Selected" ' + 'GroupBox1 + ' + Me.GroupBox1.Controls.Add(Me.rtfSummaryReport) + Me.GroupBox1.Location = New System.Drawing.Point(905, 71) + Me.GroupBox1.Margin = New System.Windows.Forms.Padding(4, 5, 4, 5) + Me.GroupBox1.Name = "GroupBox1" + Me.GroupBox1.Padding = New System.Windows.Forms.Padding(4, 5, 4, 5) + Me.GroupBox1.Size = New System.Drawing.Size(424, 632) + Me.GroupBox1.TabIndex = 12 + Me.GroupBox1.TabStop = False + Me.GroupBox1.Text = "File Issues Report" + ' 'frmImportQCData ' - Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) + Me.AutoScaleDimensions = New System.Drawing.SizeF(9.0!, 20.0!) Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font - Me.ClientSize = New System.Drawing.Size(819, 612) - Me.Controls.Add(Me.GroupBox2) + Me.ClientSize = New System.Drawing.Size(1354, 749) Me.Controls.Add(Me.GroupBox1) Me.Controls.Add(Me.grpFileContents) Me.Controls.Add(Me.btnHelp) @@ -178,13 +170,15 @@ Partial Class frmImportQCData Me.Controls.Add(Me.btnBrowse) Me.Controls.Add(Me.lblSelectFile) Me.Controls.Add(Me.txtFilePath) + Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow + Me.Margin = New System.Windows.Forms.Padding(4, 5, 4, 5) Me.Name = "frmImportQCData" + Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen Me.Text = "Import R-Instat Quality Controlled Data" CType(Me.dataGridFileContents, System.ComponentModel.ISupportInitialize).EndInit() Me.grpFileContents.ResumeLayout(False) Me.grpFileContents.PerformLayout() Me.GroupBox1.ResumeLayout(False) - Me.GroupBox2.ResumeLayout(False) Me.ResumeLayout(False) Me.PerformLayout() @@ -200,7 +194,5 @@ Partial Class frmImportQCData Friend WithEvents btnHelp As Button Friend WithEvents grpFileContents As GroupBox Friend WithEvents GroupBox1 As GroupBox - Friend WithEvents GroupBox2 As GroupBox - Friend WithEvents RichTextBox1 As RichTextBox Friend WithEvents lblFileSelection As Label End Class diff --git a/ClimsoftVer4/ClimsoftVer4/frmImportQCData.vb b/ClimsoftVer4/ClimsoftVer4/frmImportQCData.vb index 21c264aa..448011a3 100644 --- a/ClimsoftVer4/ClimsoftVer4/frmImportQCData.vb +++ b/ClimsoftVer4/ClimsoftVer4/frmImportQCData.vb @@ -6,35 +6,56 @@ Public Class frmImportQCData Private Sub frmImportQCData_Load(sender As Object, e As EventArgs) Handles MyBase.Load dataGridFileContents.Visible = False lblFileSelection.Visible = True + btnSave.Enabled = False End Sub Private Sub btnBrowse_Click(sender As Object, e As EventArgs) Handles btnBrowse.Click Using dlgOpen As New OpenFileDialog dlgOpen.Filter = "Comma separated files|*.csv" dlgOpen.Multiselect = False - dlgOpen.Title = "Open Data From File" + dlgOpen.Title = "Open QC File" If DialogResult.OK = dlgOpen.ShowDialog() Then txtFilePath.Text = dlgOpen.FileName Dim dtbQCData As DataTable = GetQCFileDataTableDefinition() FillQCFileDataFromCSV(dlgOpen.FileName, dtbQCData) If dtbQCData.Rows.Count = 0 Then - dataGridFileContents.Visible = False + btnSave.Enabled = False lblFileSelection.Visible = True + dataGridFileContents.Visible = False + dataGridFileContents.DataSource = Nothing Else + btnSave.Enabled = True + lblFileSelection.Visible = False dataGridFileContents.Visible = True dataGridFileContents.DataSource = dtbQCData + + For Each col As DataGridViewColumn In dataGridFileContents.Columns + col.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells + Next + dataGridFileContents.Columns("date_time").DefaultCellStyle = New DataGridViewCellStyle With { + .Format = "yyyy-MM-dd hh:mm:ss" + } End If End If End Using End Sub - Private Sub FillDataGridView(dtbQCData As DataTable) - dataGridFileContents.DataSource = dtbQCData - 'dataGridFileContents.Refresh() + 'Private Sub dataGridFileContents_RowPrePaint(sender As Object, e As DataGridViewRowPrePaintEventArgs) Handles dataGridFileContents.RowPrePaint + ' Dim dataGrid As DataGridView = DirectCast(sender, DataGridView) + ' If e.RowIndex <> dataGrid.NewRowIndex Then + ' Dim row As DataGridViewRow = dataGrid.Rows(e.RowIndex) + ' row.HeaderCell.Value = e.RowIndex + ' End If + 'End Sub + + Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click + If dataGridFileContents.DataSource IsNot Nothing Then + SaveQCData(dataGridFileContents.DataSource) + End If End Sub - Private Sub FillQCFileDataFromCSV(strFilePath As String, dtbQCData As DataTable) + Using fileReader As New FileIO.TextFieldParser(strFilePath) fileReader.TextFieldType = FileIO.FieldType.Delimited fileReader.SetDelimiters(",") @@ -48,13 +69,17 @@ Public Class frmImportQCData Exit Sub End If + Dim iFileRow As Integer = 1 'start at 1 because of column names Dim currentRow As String() + Dim dataRow As DataRow While Not fileReader.EndOfData Try - 'get data table row definitial - Dim dataRow As DataRow = dtbQCData.NewRow + + iFileRow = iFileRow + 1 'get file row fields currentRow = fileReader.ReadFields() + 'get data table row definitial + dataRow = dtbQCData.NewRow 'loop through usable columns while using the mapped field index to get the file field value from the file row 'add the file field values in the data row @@ -70,28 +95,37 @@ Public Class frmImportQCData Case "acquisition_type" dataRow.SetField(Of Integer)(usableCol.Key, Integer.Parse(fileFieldValue)) Case "date_time" - dataRow.SetField(Of String)(usableCol.Key, fileFieldValue) + dataRow.SetField(Of Date)(usableCol.Key, + Date.ParseExact(fileFieldValue, "yyyy-MM-dd hh:mm:ss", + System.Globalization.DateTimeFormatInfo.InvariantInfo)) Case "qc_log" dataRow.SetField(Of String)(usableCol.Key, fileFieldValue) Case "flag" dataRow.SetField(Of String)(usableCol.Key, fileFieldValue) Case "value" - dataRow.SetField(Of Integer)(usableCol.Key, Integer.Parse(fileFieldValue)) + If String.IsNullOrEmpty(fileFieldValue) Then + ElseIf Not IsNumeric(fileFieldValue) Then + AddText("Row " & iFileRow & " has a non numeric value. Row has been skipped.") + Continue While + ElseIf fileFieldValue.Contains(".") Then + AddText("Row " & iFileRow & " has a scaled value. Row has been skipped.") + Continue While + End If + dataRow.SetField(Of String)(usableCol.Key, fileFieldValue) Case Else Continue For End Select Next - 'dataRow.RowError - dtbQCData.Rows.Add(dataRow) Catch ex As FileIO.MalformedLineException - MsgBox("Line " & ex.Message & " is not valid and will be skipped.") + AddText("Row " & iFileRow & " is NOT valid and has been skipped. Error: " & ex.Message) Catch ex As Exception - MsgBox("Error " & ex.Message & ". Exiting.") + AddText("Row " & iFileRow & " is NOT valid and has been skipped. Error: " & ex.Message) End Try End While + End Using End Sub @@ -112,44 +146,44 @@ Public Class frmImportQCData dtbQCFileData.Columns.Add("qc_log", GetType(String)) dtbQCFileData.Columns.Add("flag", GetType(String)) dtbQCFileData.Columns.Add("value", GetType(String)) - '-------------------------------------------- 'PS note, intentionally 'ignore capturedBy, dataForm because they are entered by a climsoft application 'ignore period, obsLevel because no QC changes is expected and they don't define the record + '-------------------------------------------- + Return dtbQCFileData End Function - Private Function ValidateAndGetUsableFileColumns(arrFileColNames As String(), dtb As DataTable) As Dictionary(Of String, Integer) Dim dctUsableColNames As New Dictionary(Of String, Integer) - For fileColNameIndex As Integer = 0 To fileColNameIndex < arrFileColNames.Length - For Each column As DataColumn In dtb.Columns + For Each column As DataColumn In dtb.Columns + 'find column from file column names array + For fileColNameIndex As Integer = 0 To arrFileColNames.Length - 1 If column.ColumnName = arrFileColNames(fileColNameIndex) Then - 'column names from the file should be unique - If dctUsableColNames.ContainsKey(column.ColumnName) Then - MsgBox("Duplicate " & column.ColumnName & " detected") - Else - dctUsableColNames.Add(column.ColumnName, fileColNameIndex) - End If + dctUsableColNames.Add(column.ColumnName, fileColNameIndex) + Exit For End If Next Next 'validate column number If dctUsableColNames.Count <> dtb.Columns.Count Then - MsgBox("Minimum of " & dtb.Columns.Count & " columns expected") + AddText("Minimum of " & dtb.Columns.Count & " columns expected.") + AddText("Expected columns station_id, element_id, acquisition_type, date_time, qc_log, flag and value.") Return Nothing End If - Return dctUsableColNames End Function + Private Sub AddText(strText) + rtfSummaryReport.AppendText(strText) + End Sub Private Sub SaveQCData(dtbQCData As DataTable) @@ -230,5 +264,11 @@ Public Class frmImportQCData Next End Sub - + Private Sub btnClose_Click(sender As Object, e As EventArgs) Handles btnClose.Click + 'dispose contents + dataGridFileContents.DataSource = Nothing + txtFilePath.Text = "" + rtfSummaryReport.Clear() + Me.Close() + End Sub End Class \ No newline at end of file diff --git a/ClimsoftVer4/ClimsoftVer4/frmMainMenu.vb b/ClimsoftVer4/ClimsoftVer4/frmMainMenu.vb index d144f727..6ef89852 100644 --- a/ClimsoftVer4/ClimsoftVer4/frmMainMenu.vb +++ b/ClimsoftVer4/ClimsoftVer4/frmMainMenu.vb @@ -146,7 +146,8 @@ Public Class frmMainMenu End Sub Private Sub cmdQC_Click(sender As Object, e As EventArgs) Handles btnMainQC.Click - frmQC.ShowDialog() + 'frmQC.ShowDialog(Me) + frmImportQCData.ShowDialog(Me) End Sub Private Sub cmdProducts_Click(sender As Object, e As EventArgs) Handles btnMainProducts.Click