Adding a column to a Farpoint Spread grid - vb.net

I've never really used Farpoint Spread before, but I have an existing VB.NET application in which I need to add a column to a Spread grid. There is currently some code like:
For Each dr As DataRow In g_AdoRS.Rows
vaSpreadSum.SetText(1, x, dr(0)) 'pol_ser
...
vaSpreadSum.SetText(20, x, dr(19)) 'renew_pay_cd
vaSpreadSum.SetFloat(21, x, dr(20)) 'renew_tot_prem
vaSpreadSum.SetFloat(22, x, dr(21)) 'renew_pol_limit
vaSpreadSum.SetFloat(23, x, dr(22)) 'renew_ded_amt
vaSpreadSum.Col = 28
x = x + 1
Next dr
These SetFloat() and SetText() calls go from 0 to 28. So in order to add another column I added this line of code:
vaSpreadSum.SetText(28, x, dr(27)) 'agent name
and changed the vaSpreadSum.Col to 29
vaSpreadSum.Col = 29
But I am not seeing another column in my grid. Any idea why? There is no error thrown or anything like that, just no changes on the screen. I know there is probably more information needed to solve this, but even if anyone know the basics of adding a column to a Farpoint Spread grid that would be much appreciated. I found this but it doesn't seem that my application is adding columns that way, I couldn't find any calls to the AddColumns() method anywhere.
Thanks for any help!
I believe this is my Form_Load method
Private Sub FrmDetailRPC_Load(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Load
Cursor.Current = Cursors.WaitCursor
FormInit()
QryLocation()
Cursor.Current = Cursors.Default
End Sub
I'll also include FormInit() because that sounds like it might have to do with what I'm looking for
Sub FormInit()
txtBusUnit.Text = svBusUnit
stmtMktSeg()
txtProduct.Text = svProduct
txtSource.Text = svSource
txtSystem.Text = svSystem
txtCustSeg.Text = svCustSeg
stmtProduct()
txtLocation.Text = svLocation
If svLocationLabel = "Region" Then
lblLocation.Text = "Territory"
Else
lblLocation.Text = svLocationLabel
End If
lblLocation.TextAlign = ContentAlignment.TopRight
stmtLocation()
'txtPayType.Text = svPayType
txtTimePer.Text = TimeName
stmtTimePer()
End Sub
And QryLocation()
Sub QryLocation()
Dim producerID As String
'SetProductSelection()
stmtLocation()
stmtGetProductType()
stmtGetTimePeriodType()
stmtGetTimePeriod()
stmtGetProducerID()
stmtGetProducerType()
If stmtProducerType = "No Preference" Then
producerID = "NULL"
Else
producerID = "'" & stmtProducerID & "'"
End If
g_strSQL = "pc_mis_rpc_getdata_detail " & _
"'" & stmtLocationType & "'," & _
"'" & Trim(svLocation) & "'," & _
"'" & svBusUnit & "'," & _
"'" & stmtProductType & "'," & _
"'" & Trim(stmtProductDtl) & "'," & _
"'" & stmtTimePeriod & "'," & _
"'" & stmtTimePeriodType & "'," & _
"'" & stmtProducerType & "'," & _
producerID & "," & _
"'Retention'" _
& FilterQry & "," & _
"'" & Trim(txtCustSeg.Text) & "'," & _
"'" & Trim(txtSource.Text) & "'," & _
"'" & Trim(txtSystem.Text) & "'"
ProcQry()
End Sub

In your Form_Init() you will need to adjust the number of columns in spread control.
It should look something like this:
Sub FormInit()
' Add a column to the spreadsheet control
vaSpreadSum.ActiveSheet.AddColumns(29, 1)
' Code cut for brevity
End Sub
--or--
Sub FormInit()
' Add a column to the spreadsheet control
vaSpreadSum.ActiveSheet.Columns.Count = 29
' Code cut for brevity
End Sub
Another method for achieving the same thing is to open the form designer, select the spread control, display the properties window (press F4 if it isn't already open), and increase the Cols property to 29.

You increase the column as follows:
vaSpreadSum.MaxCols = 29

Related

ACCESS 365 and INSERT INTO not inserting data from FORM

I am updating a small medical database. So far all new products have been added manually / directly to a Products- table. I am creating a form to do that.
Even it is in a way very simple to do, I am facing up a problem that data is inserted correctly only if all fields have something typed in form, if any of the input boxes are left empty no new records are made.
Additionally a simple check for minimum fields is not working. It will step thru all controls correctly but does not stop even a field is left empty and its Tag has *-sign in it.
Insert into includes all fields which a defined in that table there is not any extra field in table except first field is autonumbered ID field. No need to type something in every field each time.
Pr
Private Function CheckAllFields() As Boolean
Dim Ctrl As Control
CheckAllFields = False
'Go through the controls in Form
'If control has tag (*) and it null (no value) then show alert
For Each Ctrl In Me.Controls
MsgBox Ctrl.Name
If Ctrl.Tag = "*" And IsNull(Ctrl) Then
Dim FieldName As String
FieldName = Ctrl.Name
'Show notification if field was not filled and move focus to that field
MsgBox "A required Field has not been filled."
Ctrl.SetFocus
CheckAllFields = True
Exit For
End If
Next Ctrl
MsgBox "Check fileds done"
End Function
Private Sub AddProduct_Click()
Dim strSQL As String
'SQL to insert Product
strSQL = "INSERT INTO Products([Product name],[Product description],[Finnish name],[Finnish description],[Matrix2012], " & _
"[Additional Info], [Unit], [Licence],[Remarks],Narcotic,[Asset], " & _
"[ATC], [Cathegory], [EIC code], [EIC name])" & _
" VALUES ('" & Me.txtProductName & "','" & Me.txtProductDesc & "','" & Me.txtFinnishName & "','" & Me.txtFinnishDesc & "','" & Me.ComboMatrix & "'," & _
"'" & Me.txtAdditionalInfo & "','" & Me.ComboUnit & "','" & Me.CheckLicense & "'," & _
"'" & Me.txtRemarks & "','" & Me.CheckNarcotic & "','" & Me.CheckAsset & "'," & _
"'" & Me.txtATC & "','" & Me.txtCathegory & "','" & Me.txtEICcode & "','" & Me.txtEICName & "')"
'' MsgBox strSQL
'Check the all fields have valid format
If CheckAllFields = False Then
'Execute SQL in database - insert new batch
' MsgBox "Step into Check all fields"
CurrentDb.Execute strSQL
MsgBox "A new product inserted !"
End If
Here is a debug output of my insert into command:
Debug output
Here is another output debug, now the new product is inserted correctly.
Correctly working version
Problem solved. As Craig pointed this way of incuding parameters is prone to fail.
Here is good way to solve this. Did not believe it but after I tried it worked ultimate.
MS access running SQL doesn't insert data, no error
strSQL = "INSERT INTO Products([Product name],[Product description],[Finnish name],[Finnish description],[Matrix2012], " & _
"[Additional Info], [Unit], [Licence],[Remarks],Narcotic,[Asset], " & _
"[ATC], [Cathegory], [EIC code], [EIC name])" & _
" VALUES (ptxtProductName, ptxtProductDesc,ptxtFinnishName,ptxtFinnishDesc,pComboMatrix, ptxtAdditionalInfo,pComboUnit, pCheckLicense, ptxtRemarks, pCheckNarcotic, pCheckAsset, ptxtATC, ptxtCathegory, ptxtEICCode, ptxtEICName);"
Set db = CurrentDb
Set qdf = db.CreateQueryDef(vbNullString, strSQL)
With qdf
.Parameters("ptxtProductName").Value = Me.txtProductName.Value
.Parameters("ptxtProductDesc").Value = Me.txtProductDesc.Value
.Parameters("ptxtFinnishName").Value = Me.txtFinnishName.Value
.Parameters("ptxtFinnishDesc").Value = Me.txtFinnishDesc.Value
.Parameters("pComboMatrix").Value = Me.ComboMatrix.Value
.Parameters("ptxtAdditionalInfo").Value = Me.txtAdditionalInfo.Value
.Parameters("pComboUnit").Value = Me.ComboUnit.Value
.Parameters("pCheckLicense").Value = Me.CheckLicense.Value
.Parameters("ptxtRemarks").Value = Me.txtRemarks.Value
.Parameters("pCheckNarcotic").Value = Me.CheckNarcotic.Value
.Parameters("pCheckAsset").Value = Me.CheckAsset.Value
.Parameters("ptxtATC").Value = Me.txtATC.Value
.Parameters("ptxtCathegory").Value = Me.txtCathegory.Value
.Parameters("ptxtEICCode").Value = Me.txtEICcode.Value
.Parameters("ptxtEICName").Value = Me.txtEICName.Value
.Execute dbFailOnError
End With
Debug.Print db.RecordsAffected
That check for empty fields is mystery, it works in another form so it has to be some sort of reference problem. Anyway to keep things simple this works perfectly:
If txtProductName.Value = "" Or ComboMatrix.Value = "" Or ComboUnit.Value = "" Then
'Show notification if field was not filled and move focus to that field
MsgBox "A required Field has not been filled."

How to loop through items on an other form?

So I have a three forms with text boxes, and I'm saving them to db on the last one, one is pretty huge and iterative so I'd like to write a loop. But when I try to loop through them it doesn't seem to grab them from the other form, what am I doing wrong?
For i = 1 To 12
Dim txtbox_bem As TextBox = CType(frm_new_prot_2.Controls("frm_new_prot_2.txtbox_bem1_" & i), TextBox)
Dim txtbox_soll As TextBox = CType(frm_new_prot_2.Controls("txtbox_soll1_" & i), TextBox)
Dim txtbox_messw As TextBox = CType(frm_new_prot_2.Controls("txtbox_messw1_" & i), TextBox)
Dim txtbox_einheit As TextBox = CType(Controls("frm_new_prot_2.txtbox_einheit1_" & i), TextBox)
Dim txtbox_max As TextBox = CType(Controls("frm_new_prot_2.txtbox_max1_" & i), TextBox)
Dim txtbox_min As TextBox = CType(Controls("frm_new_prot_2.txtbox_min1_" & i), TextBox)
Dim txtbox_tol As TextBox = CType(Controls("frm_new_prot_2.txtbox_tol1_" & i), TextBox)
Dim ckbox_ok As CheckBox = CType(Controls("frm_new_prot_2.ckbox_ok1_" & i), CheckBox)
command.CommandText = "INSERT INTO tb_1_" & i & " (Auftraggeber, Protokollnr, 1_" & i & "bem, 1_" & i & "soll, 1_" & i & "messw, 1_" & i & "einheit, 1_" & i & "max, 1_" & i & "min, 1_" & i & "tol, 1_" & i & "ok) VALUES ('" & Auftraggeber & "'," & Protokollnr & ",'" & txtbox_bem.Text & "','" & txtbox_soll.Text & "','" & txtbox_messw.Text & "','" & txtbox_einheit.Text & "','" & txtbox_max.Text & "','" & txtbox_min.Text & "','" & txtbox_tol.Text & "','" & ckbox_ok.Text & "')"
command.CommandType = CommandType.Text
command.ExecuteNonQuery()
MsgBox("success row " & i)
Next
As you see I tried different combinations. The error I'm getting is:
"System.NullReferenceException: 'Object reference not set to an instance of an object.' txtbox_bem was Nothing."
The line ..
Dim txtbox_bem As TextBox = CType(frm_new_prot_2.Controls("txtbox_bem1_.txtbox_bem1_" & i), TextBox)
is searching through the controls of frm_new_prot_2 for a control called "frm_new_prot_2.txtbox_bem1_" & i.
That won't exist. In the controls collection will only contain the textbox with a name of "txtbox_bem1_" & i, so the corrected version should be
Dim txtbox_bem As TextBox = CType(frm_new_prot_2.Controls("txtbox_bem1_" & i), TextBox)
The other lines in your code probably won't work either. They should probably be ..
Dim txtbox_bem As TextBox = CType(frm_new_prot_2.Controls("txtbox_bem1_" & i), TextBox)
Dim txtbox_soll As TextBox = CType(frm_new_prot_2.Controls("txtbox_soll1_" & i), TextBox)
Dim txtbox_messw As TextBox = CType(frm_new_prot_2.Controls("txtbox_messw1_" & i), TextBox)
Dim txtbox_einheit As TextBox = CType(frm_new_prot_2.Controls("txtbox_einheit1_" & i), TextBox)
Dim txtbox_max As TextBox = CType(frm_new_prot_2.Controls("txtbox_max1_" & i), TextBox)
Dim txtbox_min As TextBox = CType(frm_new_prot_2.Controls("txtbox_min1_" & i), TextBox)
Dim txtbox_tol As TextBox = CType(frm_new_prot_2.Controls("txtbox_tol1_" & i), TextBox)
Dim ckbox_ok As CheckBox = CType(frm_new_prot_2.Controls("ckbox_ok1_" & i), CheckBox)
I think you got a bit confused about how references work. :-)
Also I suspect that the data in the textboxes is the only place where you're storing the data. This isn't terribly good programming practice. For example...
Say, the data comes from an external device and you have code that reads data from the device and stores it in the textboxes. This isn't good. anyone could accidentally overwrite data in the textbox.
It would be much better to store the data in Lists or Lists of class objects. and populate the textboxes with the data. When it comes to storing the data in your db, use the data in the lists rather than the textboxes.
The user interface should never be used to store data. Hope this helps
It might be easier to debug without all the casting.
Public Class Form2
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim lst As New List(Of String)
For i As Integer = 1 To 3
Dim str1 As String = Form1.Controls("TextBox" & i).Text
lst.Add(str1)
Next
For Each s As String In lst
Debug.Print(s)
Next
End Sub
End Class
I just added the List for testing purposes.

Use SQL code in vba access

I use the following code in vba access to update a column of a table, but it is not working. Please help me.
Best regards.
Dim sqlupdate As String
sqlupdate = "UPDATE Assay" _
& "SET Assay.assay_repeat = " & 0 & "" _
& "WHERE (((Assay.[assay_repeat])= " & 1 & "));"
DoCmd.RunSQL sqlupdate
You have an extra double quote and are missing a couple of spaces - try it like this:
Dim sqlupdate As String
sqlupdate = "UPDATE Assay" _
& " SET Assay.assay_repeat = " & 0 & " _
& " WHERE (((Assay.[assay_repeat])= " & 1 & "));"
You just missed space chars at end of the table name and before where.
Dim sqlupdate As String
sqlupdate = "UPDATE Assay " _
& "SET Assay.assay_repeat = " & 0 & " " _
& "WHERE (((Assay.[assay_repeat])= " & 1 & "));"
Here is a great way to convert a SQL string to VBA code.
Creating the form
The form just needs two text boxes, and a command button. SQL statements can be quite long, so you put the text boxes on different pages of a tab control.
Create a new form (in design view.)
Add a tab control.
In the first page of the tab control, add a unbound text box.
Set its Name property to txtSql.
Increase its Height and Width so you can see many long lines at once.
In the second page of the tab control, add another unbound text box.
Name it txtVBA, and increase its height and width.
Above the tab control, add a command button.
Name it cmdSql2Vba.
Set its On Click property to [Event Procedure].
Click the Build button (...) beside this property.
When Access opens the code window, set up the code like this:
Private Sub cmdSql2Vba_Click()
Dim strSql As String
'Purpose: Convert a SQL statement into a string to paste into VBA code.
Const strcLineEnd = " "" & vbCrLf & _" & vbCrLf & """"
If IsNull(Me.txtSQL) Then
Beep
Else
strSql = Me.txtSQL
strSql = Replace(strSql, """", """""") 'Double up any quotes.
strSql = Replace(strSql, vbCrLf, strcLineEnd)
strSql = "strSql = """ & strSql & """"
Me.txtVBA = strSql
Me.txtVBA.SetFocus
RunCommand acCmdCopy
End If
End Sub
http://allenbrowne.com/ser-71.html
I recommend you use Recordsets.
Private Sub Update_My_Records(Parent As Object)
Dim Data_Recset As Object
Dim Parent_Reference As Object
Set Data_Recset = Parent_Reference.Application.DBEngine.Workspaces(0).Databases(0).OpenRecordset("SELECT * FROM Assay WHERE assay_repeat = " & 0 & ";", DB_OPEN_DYNASET)
Data_Recset.MoveLast
Data_Recset.MoveFirst
Data_Recset.Edit
Data_Recset.Fields("assay_repeat") = 1
Data_Recset.Update
Data_Recset.Close
Set Data_Recset = Nothing
End Sub
assumptions
Parent has reference to Access.Application. (I usually pass: Form.Module.Parent reference to Sub/Function)
the table or query "Assay" already exists.
You only need to update 1 row at a time
But if you want to use Queries In Your Form:
Private Sub Query_Definition_Update()
Dim Obj_Qdef As Object
Dim Query_Name As String
Query_Name = "Q_Assay"
Me.Form.Application.DBEngine.Workspaces(0).Databases(0).QueryDefs.Refresh
Set Obj_Qdef = Me.Form.Application.DBEngine.Workspaces(0).Databases(0).QueryDefs(Query_Name)
Obj_Qdef.SQL = Query_Update(1)
Debug.Print Obj_Qdef.SQL
Obj_Qdef.Execute
''When finished updating
Obj_Qdef.Close
Set Obj_Qdef = Nothing
End Sub
'------------------------------------------------------------'
Private Function Query_Update(New_Value as Integer) As String
Query_Update = "UPDATE Assay" & _
" SET Assay.assay_repeat = " & 0 & "" & _
" WHERE (((Assay.[assay_repeat])= " & New_Value & "));"
End Sub

Checked listview for duplicates

Hi Can you please help me to solve this i want to find the duplicates in listview. This is my code
For Up As Integer = lvCart.Items.Count - 1 To 1 Step -1
For down As Integer = 0 To Up - 1 Step 1
If lvCart.Items(Up).SubItems(0).Text <> lvCart.Items(down).SubItems(0).Text Then
ExecuteQry("INSERT INTO tblPurchaseOrder VALUES ('" & lvCart.Items(Up).SubItems(0).Text & "','" & dateCreated & "','" & txtTcost.Text & "','" & lblUserid.Text & "')")
ExecuteQry("INSERT INTO tblPurchaseOrder VALUES ('" & lvCart.Items(down).SubItems(0).Text & "','" & dateCreated & "','" & txtTcost.Text & "','" & lblUserid.Text & "')")
Exit For
Else
End If
Next
Next
if the nested loop found the same PONumber(lvCart.Items().SubItems(0).Text) in the listview it will be save as one transaction my code is working, it saves in the database but it show an error for duplicates
To find duplicates in your list view you can use a Dictionary to help with that. The itemDict will have no duplicates, and the duplicateItems list will contain duplicate items if you need them for some reason.
Private Sub FindListViewDups()
Dim lvCart As New ListView
lvCart.Items.Add("hi")
lvCart.Items.Add("bye")
lvCart.Items.Add("hi")
Dim itemDict As New Dictionary(Of String, String)
Dim duplicateItems As New List(Of String)
For i As Integer = 0 To lvCart.Items.Count - 1
If Not itemDict.ContainsKey(lvCart.Items(i).Text) Then
itemDict.Add(lvCart.Items(i).Text, "")
'Other non-duplicated logic goes here....
Else
duplicateItems.Add(lvCart.Items(i).Text)
End If
Next
End Sub

RecordSource in Access SQL

I have a form which allows the user to view all records with the LinkRef field equal to a specified value and also either the Clearance Applying For or Clearance Level a certain value.
LinkRef is a user ID which is pulled in using OpenArgs from the previous form. The code for the form_load I have presently is:
Private Sub Form_Load()
'MsgBox Me.OpenArgs
Me.C_LinKRef = Me.OpenArgs
Me.chbToggleEdit.Value = False
'MsgBox Me.C_LinKRef
Dim mySQL As String
mySQL = _
"Select * " & _
"From TabClearDetail " & _
"Where (C_LinKRef = " & Me.C_LinKRef & ") " & _
"And ([Clearance Applying For] = 'BPSS' " & _
"Or [Clearance Applying For] = 'BPSS (EDF)' " & _
"Or [Clearance Applying For] = 'BPSS (Magn)' " & _
"Or [Clearance Applying For] = 'BPSS (Sella)' " & _
"Or [Clearance Applying For] = 'BPSS Equiv' " & _
"Or C_ClearanceLevel = 'BPSS' " & _
"Or C_ClearanceLevel = 'BPSS (EDF)' " & _
"Or C_ClearanceLevel = 'BPSS (Magn)' " & _
"Or C_ClearanceLevel = 'BPSS (Sella)' " & _
"Or C_ClearanceLevel = 'BPSS Equiv' " & _
"Or C_ClearanceLevel = 'DESTROYED' " & _
"Or C_ClearanceLevel = 'Lapsed' " & _
"Or C_ClearanceLevel = 'NOT_FLWDUP' " & _
"Or C_ClearanceLevel = 'NOT_SPECIFIED' " & _
"Or C_ClearanceLevel = 'Refused' " & _
"Or C_ClearanceLevel = 'Withdrawn');"
Me.RecordSource = mySQL
'MsgBox Me.RecordsetClone.RecordCount
End Sub
mySQL seems to behave as it should when there are matching records. But sometimes there won't be any records because the specified person doesn't have any of these clearance levels and hasn't applied for them, then I would like the form to come up blank or a message to appear saying that there is no matching records.
Presently though if there is no matching records the form will pull in the LinkRef but fill all the other text boxes with values from a completely different record (it seems to be the last record I viewed). Not to sure how to remedy this, I tried to use the RecordsetClone.RecordCount to say if it is equal to 0 then msgbox, but it seems to late to do that as it always seems to find at least 1 entry, as even if there should be 0 it has already populated the textboxes with data from another field so 1 is found.
The LinkRef textbox is populated from OpenArgs. All other textboxes are populated using a query which looks in the TabClearDetail table and pulls the values in. I'm starting to think I'd be better either just using Queries or just using Code, but I wasn't sure how to use OpenArgs in a query and for some things it's so much quicker to make a query than code.
Here is the code for my save dialog I refer to in reply to #Roland post. This code is called in the Form_Close() sub.
Private Sub SaveDialog()
Dim Msg, Style, Title As String
Dim Response As Integer
Msg = "Would you like to save your changes?"
Style = vbYesNoCancel
Title = "Save Changes"
On Error GoTo Err_BackFromAddBPSSButton_Click
Response = MsgBox(Msg, Style, Title)
If Response = vbYes Then
'DoCmd.Close
DoCmd.OpenForm ("Basic Personal Information")
Else
If Response = vbNo Then
Me.Undo
'DoCmd.Close
DoCmd.OpenForm ("Basic Personal Information")
End If
End If
Exit_BackFromAddBPSSButton_Click:
Exit Sub
Err_BackFromAddBPSSButton_Click:
MsgBox Err.Description
Resume Exit_BackFromAddBPSSButton_Click
End Sub
Apologies for the very wordy question, hopefully all the detail is necessary and it makes sense, any suggestions HUGELY appreciated!
Try changing the order of events:
Don't set the TextBox value first. Pass the OpenArgs to the mySql string. With mySql open a recordset in VBA (OpenRecordset) and do a RecordCount. If it is zero then set the Recordsource to SELECT * FROM TabClearDetail WHERE 1=2 . Else set mySQl as the Recordsource (or pass the Recordset). Only then set the TextBox and CheckBox.
Private Sub Form_Load()
Dim i as Integer
i = Me.OpenArgs
Dim mySQL As String
mySQL = _
"Select * " & _
"From TabClearDetail " & _
"Where (C_LinKRef = " & Me.C_LinKRef & ") " & _
"And ([Clearance Applying For] IN ('BPSS','BPSS (EDF)','BPSS (Magn)','BPSS Sella)','BPSS Equiv') " & _
"Or C_ClearanceLevel IN ('BPSS','BPSS (EDF)','BPSS (Magn)','BPSS (Sella)','BPSS Equiv','DESTROYED','Lapsed','NOT_FLWDUP','NOT_SPECIFIED','Refused','Withdrawn'));"
Dim rst as Recordset
Set rst = CurrentDB.OpenRecordset(mySQL)
rst.MoveLast
rst.MoveFirst
If rst.RecordCount = 0 then
Me.RecordSource = "SELECT * FROM TabClearDetail WHERE 1=2"
Me.C_LinKRef = ""
Me.chbToggleEdit.Value = False
Else
Me.RecordSource = mySQL
Me.C_LinKRef = i
Me.chbToggleEdit.Value = False
End If
rst.Close
Set rst = Nothing
End Sub
Sorry, cannot test it here so may be a little buggy. If any problems I will check tomorrow
Using a query and passing [Forms]![BPSS Clearance].[OpenArgs] into that as well as the conditions on C_ClearanceLevel and Clearance Applying For has worked for me. No idea why the code didn't work because in theory it's doing the same thing, but I've got a solution so I'm happy. Thanks for all the suggestions