Related
I'm using a Windows Form in Visual Studio 2019 to upload an Excel file to a SQL Server database. Upload happens just fine. For simplicity; Column 'No' gets populated with values 1,2 etc. with what's included in the excel file. Column 'BUSINESS_UNIT' is left as NULL as that field is not in the excel file. What I need to do is enter a specific value, say 'ABC' for all rows of Column BUSINESS_UNIT.
No
BUSINESS_UNIT
1
NULL
2
NULL
So I'm using an update statement in my datatableadapater as below.
UPDATE MR_STAGE_SUPPLIERDELIVERY_MANUAL
SET PROCESSING_DATE = { fn NOW() },
BUSINESS_UNIT = 'ABC',
DIVISION = 'Autonomous Systems',
EAS_BUSINESS_UNIT_CD = 'TOT',
EAS_DIVISION_CD = 'AUTOSYS'
WHERE
(PERF_YEAR = #YEARINPUT) AND (PERF_MONTH = #MONTHINPUT)
This code works just as intended when I test it in Query Builder, it updates the records in SQL database. Then I added the below piece of code before debugging my winform code 'new.vb'.
Below are the functions I use to insert data from Excel to SQL database via Winform button.
Insert Function
Private Function ReturnInsertStatement(row As Integer) As String
Try
Dim tempString As String
Dim lastColumn As Integer
Dim ColumnName As String
Dim excelRange As Excel.Range
Dim filterString As String
tempString = "INSERT INTO [dbo].[MR_STAGE_SUPPLIERDELIVERY_MANUAL] (PERF_MONTH, PERF_YEAR,"
For lastColumn = 1 To 256
excelRange = objSheet.Cells(row, lastColumn)
ColumnName = excelRange.Value
filterString = "COLUMN_NAME='" + ColumnName + "'"
Dim findRow() As DataRow = BDSSMTOOLSDataSet.MR_STAGE_SUPPLIERDELIVERYNEW_COLUMNS.Select(filterString)
If findRow.Count > 0 Then
If Len(Trim(ColumnName)) > 0 Then
Me.columnsWithData = lastColumn + 1
tempString = tempString + "[" + Trim(findRow(0).Item("COLUMN_NAME").ToString) + "],"
Label5.Text = Label5.Text + " [" + Trim(Str(lastColumn)) + "]" + "(" + Trim(findRow(0).Item("DATA_TYPE").ToString) + ") " + Trim(findRow(0).Item("COLUMN_NAME").ToString) + " | "
End If
Else
If Len(Trim(ColumnName)) > 0 Then
Me.columnsWithData = lastColumn + 1
Label3.Text = Label3.Text + " [" + Trim(Str(lastColumn)) + "]" + "() " + ColumnName + " | "
End If
End If
Next
tempString = tempString.Substring(0, tempString.Length - 1) + ")"
ReturnInsertStatement = tempString
Catch ex As Exception
MsgBox(ex.ToString)
ReturnInsertStatement = ""
End Try
End Function
Return Function
Private Function ReturnValueStatement(row As Integer) As String
Try
Dim tempString As String
Dim lastColumn As Integer
Dim ColumnName As String
Dim filterString As String
tempString = " (" + perfMonthCombo.SelectedValue.ToString + "," + perfYearCombo.SelectedValue.ToString + ","
For lastColumn = 1 To Me.columnsWithData
ColumnName = excelRangeValues(row, lastColumn)
filterString = "[" + Trim(Str(lastColumn)) + "]"
If Label5.Text.Contains(filterString) Then
If Len(Trim(ColumnName)) = 0 Then
tempString = tempString + "Null,"
ElseIf Label5.Text.Contains(filterString + "(nvarchar)") Or Label5.Text.Contains(filterString + "(varchar)") Then
ColumnName = ColumnName.Replace("'", "''")
tempString = tempString + "'" + Trim(ColumnName) + "',"
ElseIf Label5.Text.Contains(filterString + "(datetime)") Or Label5.Text.Contains(filterString + "(date)") Then
Dim integerdate As Integer
If Integer.TryParse(ColumnName, integerdate) Then
ColumnName = DateTime.FromOADate(CDbl(integerdate)).ToString("MM/dd/yyyy")
End If
ColumnName = ColumnName.Replace("'", "''")
tempString = tempString + "'" + Trim(ColumnName) + "',"
Else
tempString = tempString + "" + Trim(ColumnName) + ","
End If
End If
Next
tempString = tempString.Substring(0, tempString.Length - 1) + ")"
ReturnValueStatement = tempString
Catch ex As Exception
MsgBox(ex.ToString)
ReturnValueStatement = ""
End Try
End Function
Where excel and database table is mapped
For rownum = 2 To last_row
valueString = ""
For rownum2 = 0 To 50 ' batch size
valueString = valueString + ReturnValueStatement(rownum) + ","
Label4.Text = "Rows Processing: " + Trim(Str(rownum)) + " of " + Trim(Str(last_row))
If rownum >= last_row Then Exit For
ProgressBar1.Value = rownum
rownum = rownum + 1
Next rownum2
valueString = valueString.Subs << File: VB CODE.txt >> tring(0, valueString.Length - 1)
If IsNothing(result) Then
cmd.CommandText = insertString + " VALUES " + valueString
'Console.WriteLine("T0: " + cmd.CommandText)
result = cmd.BeginExecuteNonQuery()
Else
If IsNothing(result1) Then
cmd1.CommandText = insertString + " VALUES " + valueString
' Console.WriteLine("T1: " + cmd1.CommandText)
result1 = cmd1.BeginExecuteNonQuery()
Else
cmd2.CommandText = insertString + " VALUES " + valueString
'Console.WriteLine("T2: " + cmd2.CommandText)
result2 = cmd2.BeginExecuteNonQuery()
cmdvalue2 = cmd2.EndExecuteNonQuery(result2)
'Console.WriteLine("T2: Command complete. Affected {0} rows.", cmdvalue2)
If ProgressBar2.Value + cmdvalue2 < ProgressBar2.Maximum Then
ProgressBar2.Value = ProgressBar2.Value + cmdvalue2
Else
ProgressBar2.Value = ProgressBar2.Maximum
End If
Label6.Text = "Records in the Database: " + Str(ProgressBar2.Value)
result2 = Nothing
End If
End If
If IsNothing(result) = False Then
If result.IsCompleted Or rownum >= last_row Then
cmdValue = cmd.EndExecuteNonQuery(result)
' Console.WriteLine("T0: Command complete. Affected {0} rows.", cmdValue)
If ProgressBar2.Value + cmdValue < ProgressBar2.Maximum Then
ProgressBar2.Value = ProgressBar2.Value + cmdValue
Else
ProgressBar2.Value = ProgressBar2.Maximum
End If
Label6.Text = "Records in the Database: " + Str(ProgressBar2.Value)
result = Nothing
End If
End If
If IsNothing(result1) = False Then
If result1.IsCompleted Or rownum >= last_row Then
cmdvalue1 = cmd1.EndExecuteNonQuery(result1)
' Console.WriteLine("T1: Command complete. Affected {0} rows.", cmdvalue1)
If ProgressBar2.Value + cmdvalue1 < ProgressBar2.Maximum Then
ProgressBar2.Value = ProgressBar2.Value + cmdvalue1
Else
ProgressBar2.Value = ProgressBar2.Maximum
End If
Label6.Text = "Records in the Database: " + Str(ProgressBar2.Value)
result1 = Nothing
End If
End If
Try
cmd.CommandTimeout = 10000
Me.Validate()
Me.MR_STAGE_SUPPLIERDELIVERYNEW_MANUALTableAdapter.Fill(Me.BDSSMTOOLSDataSet.MR_STAGE_SUPPLIERDELIVERYNEW_MANUAL, perfYearCombo.SelectedValue, perfMonthCombo.SelectedValue)
Me.MR_STAGE_SUPPLIERDELIVERYNEW_MANUALTableAdapter.Update(Me.BDSSMTOOLSDataSet.MR_STAGE_SUPPLIERDELIVERYNEW_MANUAL)
DataisSavedtoDB = True
perfMonthYear = Trim(perfMonthCombo.SelectedValue.ToString) + "/01/" + Trim(perfYearCombo.SelectedValue.ToString)
Label9.Text = "Current Number of Records for " + Trim(perfMonthCombo.SelectedValue.ToString) + "/" + Trim(perfYearCombo.SelectedValue.ToString) Me.BDSSMTOOLSDataSet.MR_STAGE_SUPPLIERDELIVERYNEW_MANUAL.Count.ToString
Catch ex As Exception
MsgBox(ex.ToString)
End Try
MR_STAGE_SUPPLIERDELIVERYNEW_COLUMNSTableAdapter1.Connection.Close()
When I debug this application; insert statement TableAdapter.Fill works as intended, inserting all the excel data into the SQL data, but the update statement TableAdapter.Update is not updating any of the data in my SQL database. It does not throw any error, data in SQL server database is just not updated, i.e. BUSINESS_UNIT is still NULL in database.
I attempted below solutions all day, but had no luck.
Setting dataset properties to "Do not Copy"
Wrapping up the update statement within Try Catch
Using Bindingsource.Endif() after the update statement
Attempted to use .AcceptChanges() method, but this throws an error saying that its not a member of the tableadapter
Any kind help to get this working is very much appreciated!
I'm getting a type mismatch in the Dlookup below. Note: the ID column in the Results2 Table is formatted as a Number.
If DLookup("[Result" & i & "]", "Results2", "[ID] = '" & newid & "'") <> Me.Controls("C" & 3 + column & "R" & i + j).Value Then
I've tried changing the newid from a string to an Integer or a Long, but I still get this error.
Full code for this Sub below, if more info is needed.
Private Sub BtnSave_Click()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim rs2 As DAO.Recordset
Dim rs3 As DAO.Recordset
Dim i As Integer
Dim j As Integer
Dim ans As Integer
Dim column As Integer
Dim colcnt As Integer
Dim newid As String
If IsNull(Me.Spindle3.Value) = False Then
colcnt = 3
ElseIf IsNull(Me.Spindle2.Value) = False Then
colcnt = 2
Else
colcnt = 1
End If
column = 1
Set db = CurrentDb
Set rs = db.OpenRecordset("Results")
Set rs2 = db.OpenRecordset("Results2")
Set rs3 = db.OpenRecordset("Results3")
Linestart:
j = 0
rs.AddNew
newid = rs![ID].Value
If Me.Result1.Value = "Fail" Or Me.Result2.Value = "Fail" Or Me.Result1.Value = "Fail" Then
If column = 1 Then
ans = MsgBox("This is a FAILING Result. Do you with to save it?", vbYesNo)
If ans = 7 Then GoTo Lineend
End If
ElseIf Me.Result1.Value = "Incomplete" Or Me.Result2.Value = "Incomplete" Or Me.Result2.Value = "Incomplete" Then
If column = 1 Then
ans = MsgBox("Testing is not finished for this part. Do you with to save and close now?", vbYesNo)
If ans = 7 Then GoTo Lineend
End If
End If
With rs
![PartNum] = Me.FilterPartNumber.Value
![INDNum] = Me.INDNum.Value
![DateTime] = Me.DateTime.Value
![HTLotNum] = Me.HTLotNum.Value
![Operator] = Me.Inspector.Value
![Spindle] = Me.Controls("Spindle" & column).Value
![TypeofCheck] = Me.InspType.Value
![OverallResult] = Me.Controls("Result" & column).Value
End With
rs2.AddNew
With rs2
![ID] = newid
![PartNum] = Me.FilterPartNumber.Value
![Plant] = Me.plantnum.Value
![DateTime] = Me.DateTime.Value
![HTLotNum] = Me.HTLotNum.Value
![Notes] = Me.Notes.Value
![Spindle] = Me.Spindle.Value
![TypeofCheck] = Me.InspType.Value
![OverallResult] = Me.Result1.Value
End With
rs3.AddNew
With rs3
![ID] = newid
![PartNum] = Me.FilterPartNumber.Value
![DateTime] = Me.DateTime.Value
End With
If IsNull(Me.HTLotNum.Value) = True Then
rs![HTLotNum] = "(blank)"
rs![HTLotNum] = "(blank)"
End If
For i = 1 To 90 Step 1
If i + j >= 90 Then
i = 90
GoTo Line1
End If
If IsNull(Me.Controls("C3R" & i + j).Value) = True Then
j = j + 1
End If
If i + j >= 90 Then
i = 90
GoTo Line1
End If
If IsNull(Me.Controls("C2R" & i + j).Value) = True Then GoTo Line1
rs("Char" & i) = Me!ListFeatures.column(1, i - 1)
rs("Desc" & i) = Me!ListFeatures.column(2, i - 1)
rs("Spec" & i) = Me!ListFeatures.column(3, i - 1) & " " & Me!ListFeatures.column(6, i - 1)
rs2("SC" & i) = Me!ListFeatures.column(4, i - 1)
rs2("Location" & i) = Me!ListFeatures.column(5, i - 1)
rs2("Result" & i) = Me.Controls("C" & 3 + column & "R" & i + j).Value
rs3("Coding" & i) = Me!ListCoding.column(1, i - 1)
Line1:
Next
rs.Update
rs2.Update
rs3.Update
For i = 1 To 90 Step 1
If i + j >= 90 Then
i = 90
GoTo Line1
End If
If IsNull(Me.Controls("C3R" & i + j).Value) = True Then
j = j + 1
End If
If i + j >= 90 Then
i = 90
GoTo Line1
End If
If DLookup("[Result" & i & "]", "Results2", "[ID] = '" & newid & "'") <> Me.Controls("C" & 3 + column & "R" & i + j).Value Then
MsgBox "Results not saved! Document results on paper and contact the database engineer regarding this error."
GoTo Lineend:
End If
Next
If column < colcnt Then
column = column + 1
GoTo Linestart
End If
Line2:
Forms![Landing Page]![LIstIncomplete].Requery
DoCmd.Close
Lineend:
End Sub
Per one of the comments, I updated the trouble line to the line below. I'm almost certain that was how I initially wrote this line and added the apostrophes as an attempt to fix.
If DLookup("[Result" & i & "]", "Results2", "[ID] = " & newid) <> Me.Controls("C" & 3 + column & "R" & i + j).Value Then
I had to fix one of my Goto's as well, one of them led to an infinite loop, but now everything is working as intended.
Thanks for the help!
I am trying to fill a range with a formula and continue to get a runtime error '1004'. The error occurs at the line I have starred Sheets("Forecast").Range("H125").Formula = formulaTest. The code in my Sub is as follows:
Sub FirmShareFill()
Dim RampUp As Range
Dim RampBas As Range
Dim RampDn As Range
Dim Numbering As Range
Dim Approval As Range
Dim PeakShare As Range
Dim tcount As Byte
Dim bcount As Byte
Dim ubdcount As Byte
Dim yearRange2 As Byte
year = Worksheets("Inputs").Range("B6").Value
cntry = Worksheets("Inputs").Range("B5").Value
bnd = Worksheets("Inputs").Range("B3").Value
typ = Worksheets("Inputs").Range("B2").Value
cat = Worksheets("Inputs").Range("B4").Value
tcount = bnd * cat + bnd
ubdcount = tcount * 2 + 1
yearCount = year * 4 - 1
For ubd = 1 To 3
For t = 1 To typ
For b = 1 To bnd
For c = 1 To cat
For i = 1 To cntry
Set RampUp = Columns(7).Find(What:="Ramp_Up" & i, MatchCase:=True).Offset(0, 1)
Set RampBas = Columns(7).Find(What:="Ramp_Bas" & i, MatchCase:=True).Offset(0, 1)
Set RampDn = Columns(7).Find(What:="Ramp_Dn" & i, MatchCase:=True).Offset(0, 1)
Set Numbering = Sheets("Inputs").Range("B13")
Set Approval = Columns(6).Find(What:="Approval", MatchCase:=True).Offset(i, 2 + ubd)
bcount = c + (cat + 1) * (b - 1)
If t = 1 And b = 1 And ubd = 1 Then
Set PeakShare = Columns(5).Find(What:="Peak Share", MatchCase:=True).Offset(4 + i, c)
ElseIf t = 1 And b > 1 And ubd = 1 Then
Set PeakShare = Columns(5).Find(What:="Peak Share" & c, MatchCase:=True).Offset(4 + i, bcount)
ElseIf t > 1 And b = 1 And ubd = 1 Then
Set PeakShare = Columns(5).Find(What:="Peak Share" & c, MatchCase:=True).Offset(4 + i, c + tcount)
ElseIf t > 1 And b > 1 And ubd = 1 Then
Set PeakShare = Columns(5).Find(What:="Peak Share" & c, MatchCase:=True).Offset(4 + i, tcount + bcount)
ElseIf t = 1 And b = 1 And ubd = 2 Then
Set PeakShare = Columns(5).Find(What:="Peak Share", MatchCase:=True).Offset(4 + i, c + ubdcount)
ElseIf t = 1 And b > 1 And ubd = 1 Then
Set PeakShare = Columns(5).Find(What:="Peak Share" & c, MatchCase:=True).Offset(4 + i, bcount + ubdcount)
ElseIf t > 1 And b = 1 And ubd = 1 Then
Set PeakShare = Columns(5).Find(What:="Peak Share" & c, MatchCase:=True).Offset(4 + i, c + tcount + ubdcount)
ElseIf t > 1 And b > 1 And ubd = 1 Then
Set PeakShare = Columns(5).Find(What:="Peak Share" & c, MatchCase:=True).Offset(4 + i, tcount + bcount + ubdcount)
ElseIf t = 1 And b = 1 And ubd = 3 Then
Set PeakShare = Columns(5).Find(What:="Peak Share", MatchCase:=True).Offset(4 + i, c + 2 * ubdcount)
ElseIf t = 1 And b > 1 And ubd = 3 Then
Set PeakShare = Columns(5).Find(What:="Peak Share" & c, MatchCase:=True).Offset(4 + i, bcount + 2 * ubdcount)
ElseIf t > 1 And b = 1 And ubd = 3 Then
Set PeakShare = Columns(5).Find(What:="Peak Share" & c, MatchCase:=True).Offset(4 + i, c + tcount + 2 * ubdcount)
ElseIf t > 1 And b > 1 And ubd = 3 Then
Set PeakShare = Columns(5).Find(What:="Peak Share" & c, MatchCase:=True).Offset(4 + i, tcount + bcount + 2 * ubdcount)
End If
Dim formulaTest As String
formulaTest = "=IF(" & Numbering.Address(False, False) & "<" & Approval.Address & ","", " & PeakShare.Address & " * " & RampUp.Address & ")"
If ubd = 1 Then
**Sheets("Forecast").Range("H125").Formula = formulaTest**
ActiveCell.Offset(1, 0).Select
ElseIf ubd = 2 Then
Range(ActiveCell, ActiveCell.Offset(0, yearRange2)).Formula = "=IF(" & Numbering.Address(False, False) & " < " & Approval.Offset(1, 0).Address & ","", " & PeakShare.Address & " * " & RampBas.Address & ""
ElseIf ubd = 3 Then
Range(ActiveCell, ActiveCell.Offset(0, yearRange2)).Formula = "=IF(" & Numbering.Address(False, False) & " < " & Approval.Offset(1, 0).Address & ","", " & PeakShare.Address & " * " & RampDn.Address & ""
End If
Next i
ActiveCell.Offset(1, 0).Select
Next c
Next b
Next t
Next ubd
End Sub
I believe the error may have something to do with how I declared the range "numbering" range, but as of yet I have been unable to figure it out. I have used this code on the same sheet many times, the only difference being that I have set a range, numbering, on a different sheet.
This should work:
formulaTest = "=IF(" & Numbering.Address(False, False) & "<" & Approval.Address & ",""""," & PeakShare.Address & "*" & RampUp.Address & ")"
As #Comintern pointed out, you need to use """" to include double empty speech marks in your formula. I also removed the spaces either side of the *
change
IF(" & Numbering.Address(False, False) & "<" & Approval.Address & ","", " & PeakShare.Address & " * " & RampUp.Address & ")"
to
IF(" & Numbering.Address(False, False) & "<" & Approval.Address & ","""", " & PeakShare.Address & " * " & RampUp.Address & ")"
Instead of counting how many " you have, you can use Chr(34) inside " to have a Formula check for ".
In your case, use:
"=IF(" & Numbering.Address(False, False) & "<" & Approval.Address & "," & Chr(34) & ", " & PeakShare.Address & " * " & RampUp.Address & ")"
I'm trying to make an automated templated with VBA and this code seems to run fine when I enter in a low number of "pages", but when I enter in something such as the following into the prompts it gives me a run-time error 1004: 14 pages: 41, 26, 19, 28, 26, 28, 17, 26, 21, 19, 19, 10, 23, 28.
Public TitleSize As Integer
Public MostValves() As Integer
Public TotalValves As Integer
Public TitleBlockSize As Integer
Function ConvertToLetter(iCol As Integer) As String
Dim iAlpha As Integer
Dim iRemainder As Integer
iAlpha = Int(iCol / 27)
iRemainder = iCol - (iAlpha * 26)
If iAlpha > 0 Then
ConvertToLetter = Chr(iAlpha + 64)
End If
If iRemainder > 0 Then
ConvertToLetter = ConvertToLetter & Chr(iRemainder + 64)
End If
End Function
Sub ManualValve()
'On Error GoTo ErrHandler
'On Error Resume Next
Worksheets(1).Activate
ActiveSheet.Name = "Valve List"
ActiveSheet.Cells.Clear
PnIDPage = InputBox("How many pages are on your P&ID?")
'Values for Number of Pages: 14
Dim i As Integer
TotalValves = 0
ReDim MostValves(PnIDPage)
For i = 0 To PnIDPage - 1
ValveCount = InputBox("How many valves are on page " & i + 1 & " ?")
'Values for valves: 41, 26, 19, 28, 26, 28, 17, 26, 21, 19, 19, 10, 23, 28
If IsNumeric(ValveCount) Then
MostValves(i) = ValveCount
TotalValves = TotalValves + ValveCount
Else
MsgBox ("You did not enter a valid number")
'GoTo ErrHandler
End If
Next i
Dim Title As Variant
Response = MsgBox(prompt:="Do you want to use the default titleblock? (Count, Valve, Module, Note)", Buttons:=vbYesNo)
If Response = vbYes Then
Title = Array("Count", "Valve", "Module", "Note")
TitleSize = UBound(Title, 1) - LBound(Title, 1) + 1
Else
Title = Array("Count", "Valve", "Module")
TitleSize1 = UBound(Title, 1) - LBound(Title, 1) + 1
XtraCol = InputBox("How many extra columns would you like to add?")
ReDim Preserve Title(XtraCol + TitleSize1 - 1)
TitleSize = UBound(Title, 1) - LBound(Title, 1) + 1
For i = TitleSize1 + 1 To TitleSize
XtraTitle = InputBox("Extra Title " & i & "?")
Title(i - 1) = XtraTitle
Next i
End If
Dim TitleBlock As Variant
TitleBlock = Array("Project Number", "Project Name", "By", "Rev", "Date")
TitleBlockSize = UBound(TitleBlock, 1) - LBound(TitleBlock, 1) + 1
Range(ConvertToLetter(1) & "1:" & ConvertToLetter(1) & TitleBlockSize) = Application.Transpose(TitleBlock)
Dim Maximum As Integer
Dim ValveNum() As Integer
Dim TempSize As Integer
TempSize = 1
Maximum = WorksheetFunction.Max(MostValves) + 1
For i = 0 To PnIDPage - 1
Do Until MostValves(i) <> 0
i = i + 1
Loop
ReDim ValveNum(MostValves(i))
For j = 0 To MostValves(i)
ValveNum(j) = j + 1
Next j
MsgBox TempSize
If i Mod 2 = 0 Then
Worksheets(1).Range(ConvertToLetter(TempSize) & TitleBlockSize + 2 & ":" & ConvertToLetter(TempSize + TitleSize - 1) & Maximum + TitleBlockSize).Interior.ColorIndex = 42
Else
'This is where I encounter the run-time error
Worksheets(1).Range(ConvertToLetter(TempSize) & TitleBlockSize + 2 & ":" & ConvertToLetter(TempSize + TitleSize - 1) & Maximum + TitleBlockSize).Interior.ColorIndex = 43
End If
Worksheets(1).Range(ConvertToLetter(TempSize) & TitleBlockSize + 2 & ":" & ConvertToLetter(TempSize) & CStr(MostValves(i) + 1 + TitleBlockSize)). _
Resize(MostValves(i), 1) = Application.Transpose(ValveNum)
Worksheets(1).Range(ConvertToLetter(TempSize + 2) & TitleBlockSize + 2 & ":" & ConvertToLetter(TempSize + 2) & CStr(MostValves(i) + 1 + TitleBlockSize)) = "00" & CStr(i + 1)
Worksheets(1).Range(ConvertToLetter(TempSize) & TitleBlockSize + 1 & ":" & ConvertToLetter(TempSize + TitleSize - 1) & TitleBlockSize + 1) = Title
TempSize = TempSize + TitleSize
Worksheets(1).Range(ConvertToLetter(TempSize - 1) & TitleBlockSize + 1 & ":" & ConvertToLetter(TempSize - 1) & Maximum + TitleBlockSize). _
Borders(xlEdgeRight).Weight = xlMedium
Next i
Cells(1, 4) = "Total Valve Count"
Cells(1, 5) = TotalValves
Range("A1:" & ConvertToLetter(TempSize) & Maximum + TitleBlockSize).HorizontalAlignment = xlCenter
Range("A1:A" & TitleBlockSize).HorizontalAlignment = xlLeft
Columns("A:" & ConvertToLetter(TempSize)).AutoFit
Range("A1:" & ConvertToLetter(TempSize) & TitleBlockSize + 1).Font.Bold = True
Range("A" & TitleBlockSize + 1 & ":" & ConvertToLetter(TempSize - 1) & TitleBlockSize + 1).Interior.ColorIndex = 1
Range("A" & TitleBlockSize + 1 & ":" & ConvertToLetter(TempSize - 1) & TitleBlockSize + 1).Font.Color = vbWhite
Range("A" & Maximum + TitleBlockSize & ":" & ConvertToLetter(TempSize - 1) & Maximum + TitleBlockSize). _
Borders(xlEdgeBottom).Weight = xlMedium
'ErrHandler:
'MsgBox "An error has occurred. The macro will end."
End Sub
The problem does not depend on your Valve, but on your ConvertToLetter function. In fact, at some point the error occurs because the function returns an invalid range letter:
input: iCol = 53
return: "A["
Clearly, when you try to call the Range("A[2"), this raises the exception.
The code inside your function is not solid because converts the number into letter with:
ConvertToLetter = Chr(iAlpha + 64)
The Chr() function returns the value associated to the index from the characters collection, which is a unique chars list and cannot be used as you try to do there.
I would just replace your ConvertToLetter function with a more solid one, such as the following:
Function ConvertToLetter(iCol As Integer) As String
Dim vArr
vArr = Split(Cells(1, iCol).Address(True, False), "$")
ConvertToLetter = vArr(0)
End Function
...which has been kindly provided by brettdj in one of his precious answers (don't forget to give him an upvote for this piece of gold ;).
P.s. note that this explain also why a low number would not raise the exception: as long as the number is small, your function doesn't need to append a second letter to the output so it remains consistent. But as soon as it has to do that, CRASH ;)
Use the above function, it's way safer because it just retrieves the Range address from the Cells object. Your code will work fine once you will replace your old function with the new one above.
I am using Vb to take a .txt file, parse it, and check for errors. My code works just fine, however, the code does not go through the entire file. It stops, on average, 20 lines shy of the EOF.
I am using the following
For Each lines As String In System.IO.File.ReadLines(myFile)
from here I parse the line and see if it needs any fixes.
Is there something that I'm missing or something that just cant be avoided.
The files that I'm reading in are about 150,000 KB to 230,000 KB and over 2 million lines.
As requested, the following is my code. Warning, I just started using Vb...
Module Module1
Sub Main()
Dim root As String = "C:\Users\mschramm\Documents\Agco\WindSensor\Data\filestobecleaned\"
Dim datafile As String = root & "ES.txt"
Dim outfile As String = root & "temptry.txt"
Dim output As System.IO.StreamWriter = My.Computer.FileSystem.OpenTextFileWriter(outfile, False)
Dim k As UInteger = 0
Dim fixes As UInteger = 0
Dim time As ULong = 0
Dim count As UInteger = 0
Dim n As UInteger = 0
Dim LineCount As UInteger = 0
Dim TimeStep As ULong = 100
Dim Solar As UInteger = 0
For Each lines As String In System.IO.File.ReadLines(datafile)
LineCount = LineCount + 1
'Console.WriteLine(LineCount)
Dim parsedline As String() = Split(lines, ",")
If IsNumeric(parsedline(0)) = True And UBound(parsedline) = 8 Then
'TimeStep = parsedline(0) - time
Solar = parsedline(1)
time = parsedline(0)
output.WriteLine(lines & " Good Line")
count = count + 1
Else
Dim j As UInteger = 0
Dim ETX As Integer = 0
Dim STX As Integer = 0
Dim datacheck As Boolean = False
Dim fixedline As String = ""
Dim newtime As ULong = 0
For j = 0 To UBound(parsedline)
Dim a As Char = parsedline(j)
If a = (Chr(3)) Then ETX = j
If a = (Chr(2)) Then STX = j
Next
j = 0
If (STX < ETX) And (ETX - STX) = 6 And STX >= 2 Then
If Len(parsedline(STX + 1)) = 8 And Len(parsedline(STX + 2)) = 8 And Len(parsedline(STX + 3)) = 8 Then
Dim g = Len(parsedline(STX - 2))
While (j < g) And datacheck = False
If IsNumeric(parsedline(STX - 2)) Then
If parsedline(STX - 2) - time < 10000 And parsedline(STX - 2) - time > 0 Then
newtime = Right(parsedline(STX - 2), Len(parsedline(STX - 2)))
Solar = parsedline(STX - 1)
'TimeStep = newtime - time
fixedline = newtime & "," & parsedline(STX - 1) & "," & parsedline(STX) & "," & parsedline(STX + 1) & "," & parsedline(STX + 2) & "," & parsedline(STX + 3) & "," & parsedline(STX + 4) & "," & parsedline(STX + 5) & "," & parsedline(STX + 6) & " Fixed Line"
datacheck = True
Else
j = j + 1
parsedline(STX - 2) = Right(parsedline(STX - 2), Len(parsedline(STX - 2)) - 1).ToString
End If
Else
j = j + 1
parsedline(STX - 2) = Right(parsedline(STX - 2), Len(parsedline(STX - 2)) - 1).ToString
End If
End While
End If
End If
If (STX < ETX) And (ETX - STX) = 6 And STX = 0 Then
If Len(parsedline(1)) = 8 And Len(parsedline(2)) = 8 And Len(parsedline(3)) = 8 And Len(parsedline(4)) = 1 And Len(parsedline(5)) = 2 And Len(parsedline(6)) = 3 Then
newtime = time + TimeStep
fixedline = newtime & "," & Solar & "," & parsedline(STX) & "," & parsedline(STX + 1) & "," & parsedline(STX + 2) & "," & parsedline(STX + 3) & "," & parsedline(STX + 4) & "," & parsedline(STX + 5) & "," & parsedline(STX + 6) & " Fixed Line Gave Time and Solar"
datacheck = True
End If
End If
If newtime < time And newtime > 1000 Then
Dim badtime As ULong = newtime
Dim firstdig As ULong = time
Dim loopcount As UInteger = 0
While firstdig > 9
firstdig = firstdig / 10
loopcount = loopcount + 1
End While
firstdig = firstdig * (10 ^ loopcount)
If (firstdig + badtime) > time Then
newtime = firstdig + badtime
If (newtime - (10 ^ loopcount)) > time Then
newtime = newtime - (10 ^ loopcount)
End If
End If
End If
If datacheck = True Then
k = k + 1
If (newtime > 500) Then
output.WriteLine(fixedline)
'count = count + 1
time = newtime
End If
End If
If datacheck = False Then
n = n + 1
If STX >= 0 And ETX > 0 And ETX - STX < 9 Then
Console.WriteLine(LineCount)
'n = n + 1
End If
End If
End If
Next
Console.WriteLine(count & " Good lines")
Console.WriteLine(k & " Lines Corrected")
Console.WriteLine(LineCount & " Total Lines")
Console.WriteLine(n & " Lines were thrown out")
Console.WriteLine(n / LineCount * 100 & "% thrown out")
End Sub
End Module
and here is a sample of the data
Time: 16:52:18.0
Date: 11/6/2014
Time,Sensor1,U,V,W
544161,219,Q,-001.341,+000.947,+000.140,M,00,17
544284,218,Q,-001.207,+001.074,+000.225,M,00,1C
544361,220,Q,-000.935,+000.898,+000.187,M,00,17
544460,220,Q,-001.299,+001.151,-000.009,M,00,17
This is what the last 10 lines look like
Q,+001.681,-003.510,-0356154697,236,Q,+000.826,-002.744,-000.559,M,00,19
Q,+000.474,-002.789,-0356155062,234,Q,+000.400,-002.975,+000.438,M,00,1D
Q,+000.813,-002.934,-0356155297,236,Q,+000.146,-002.129,-000.235,M,00,16
Q,+000.494,-002.234,+0356155497,236,Q,+000.681,-001.996,-000.248,M,00,1F
Q,+000.800,-001.999,-0356155697,236,Q,+001.181,-002.883,-000.795,M,00,1A
356156060,233,Q,+000.400,-002.106,+000.251,M,00,18
356156296,235,Q,+000.888,-001.026,+000.442,M,00,10
356156495,236,Q,+000.570,-001.694,+000.589,M,00,13
356156695,236,Q,+001.495,-002.177,-000.035,M,00,15
356157060,234,Q,+000.770,-003.484,-000.161,M,00,14
for this file, the code makes it to the 6th to last line.
Thanks to mafafu for pointing out the solution.
I never closed the file, so the addition of output.Close() fixed everything.
Once again, thank you mafafu.