Access vba pass variable into code - vba

I'm in Access 07 trying to pass a variable to a line of code. The purpose is to make an array of field names and then loop over the array performing the same action on each field. I've simplified it down to avoid any potential problems with the array or the loop.
In any other language I am familiar with it would be pretty simple, but I can't seem to format it in VB.
Me.FeildName.Locked = True
would be the static code, and I think the variable code would look something like this:
Dim Temp as String
Temp="FieldName"
Me.[Temp].Locked = True
but it keeps giving me an error that says "can't find the field '|' referred to in your expression", so it's not reading the value of the variable.
How do I get it to read the variable in the command?
Alternatively, I've tried to concatenate strings into a line of code:
Dim CodeLine As String
Dim TestName As String
TestName = "FieldName"
CodeLine = "Me.[" & TestName & "].Locked = True"
This creates a string that looks like functional code but how would I run it?
Thanks

If Me is a form, you need
Temp = "FieldName"
Me.Controls(Temp).Locked = True

Dick Kusleika's answer is the way to go, but for completeness' sake, you can do also something like this:
For i = LBound(strControlNames) To UBound(strControlNames)
CallByName Forms![MyFormName].Controls(strControlNames(i)), "Locked", VbLet, "True"
Next
strControlNames would be the array with your control names.

Related

for each loop only grabbing the last value of the string array

Note: I'm not posting all code due to it's over 500 lines, I'll show a summary of what I'm trying to accomplish and the issue:
I have a string array that looks like this:
New_BMWM3889;New_LEXIS600;789858;Used_VOL9998
I need to call a routine (the same routine) that will add formatting to the value. I've tried a for each loop, but it's only grabbing the last value of the string array.
I've tried something like this:
dim cars as String = "New_BMWM3889;New_LEXIS600;789858;Used_VOL9998"
dim tmp as String() = cars.Split(";")
dim vin as String
For Each c in tmp
If p.Conatains("New") Then
vin = FormatVin("New", "#", newFormat('0000'))
Else
vin = FormatVin("No Model", "&", newFormat('####'),
End If
Next
so, I have to call the same routine and pass different parameters to the FormatVin routine, however, when I run this I'm only getting the last value of the string array. The formatVin does format validation and will change the format if needed, but that's not the issue, how can I call that same routine but pass different parameters based on if the string in the string array has a prefix or not? Then once the formatting is completed, all of the new formatted values will be passed into a String builder to be used to pass to SQL,
so,
Need to grab all values from the string array
call the routine with the correct parameters based off of the string value.
take all the new formatted strings and passed as one string into a new routine that builds a SQL statement. I know it's a mess, and I'm not sure if it can really be done cleanly if at all. So at the end I should have so I can pass this into my where clause
New_BMWM3889000;New_LEXIS600000;000000789858;Used_VOL9998000
It's hard to say exactly but I think that you should be using something along these lines:
Dim cars = "New_BMWM3889;New_LEXIS600;789858;Used_VOL9998"
Dim tmp = cars.Split(";"c)
For i = 0 To tmp.GetUpperBound(0)
Dim vin = tmp(i)
If vin.Conatains("New") Then
vin = FormatVin("New", vin, newFormat('0000'))
Else
vin = FormatVin("No Model", vin, newFormat('####'),
End If
tmp(i) = vin
Next
cars = String.Join(";", tmp)
It seems like you need to get data out of and into that array. You haven't told us what FormatVin does but I would also assume that you have to pass in the data from the array and get back out a modified version to put back into the array. I might be off on some of the detail, given your vague explanation, but I think this is the basic structure you need.

CSV Data handling - vb.net

I've been asked at work to create a project to open a CSV and then use a set of conditions to change and save the data using Visual Basic.net (2010)
Although I am comfortable creating files in vb and opening them again into vb, I don't know how to declare the fields so I can query them. For example:
if field1 = "Yes" and field2 = "Blue" then textbox1.text = "abcd"
Then at a later stage I want to export a file which I'm happy doing where it writes lines to create a new CSV which could be Field1, textbox1.text, Field3 and so on
Also, would I have to declare line1.field1 and line2.field1 or could I declare line2.field1 as field25 for example or whatever the next sequential number may be?
Thanks
How are you going to read from the file?
If you do File.ReadAllLines
what does it return? A string array.
Does a string array have properties like line1? No, but they do have indexers.
How do you access an element in a string array? With a indexer,
e.g. array(0).
Does an string have properties like field1? Nope.
Can you use String.Split to split on the commas and separate the fields? Yes.
Could you write a class that has specific properties defined for each field that has a constructor that'd take a string that represents a row and put the value into the correct fields? Yes.
Could the same class know how to convert itself into a single CSV style line? Yup.
Are there other library that could help you do this? Probably.
All that being said, you can probably get away with doing something simple like this (warning: naive code sample):
Dim fileName = "C:\testFile.csv"
Dim lines = File.ReadAllLines(fileName)
Dim output As New List(Of String)
For Each line In lines
Dim fields = line.Split(","c)
fields(0) = "000" 'Blank out number
If fields(3) = "Y" Then 'Change Y to True
fields(3) = "True"
End If
output.Add(String.Join(","c, fields))
Next
File.WriteAllLines(fileName, output)
I gave it input that looked like this:
123,abc,Y,Y,N
456,def,Y,N,Y
789,ghi,N,Y,Y
012,jkl,N,N,N
and it changed the file to this:
000,abc,Y,True,N
000,def,Y,N,Y
000,ghi,N,True,Y
000,jkl,N,N,N
Utilities for working with CSV will do a better job than this. There are various ways this won't work (doesn't handle any escape sequences, etc.) but this could be sufficient if you're just wanting to do something quick and dirty and don't need to worry about some things. At the very least hopefully it'll give you a better understanding of how you'd go about solving a problem like this.
I'd recommend writing the output to a different file to test.

Can you edit the Value property of a named excel object with VBA code?

ThisWorkbook.Names("numWorkersCompEntries").Value = ThisWorkbook.Names("numWorkersCompEntries").Value + 1
I would like to store an incrementing variable in the name manager rather than storing it somewhere in the spreadsheet so that I can manipulate it by name. The above code seems intuitive to me but I am getting a type mismatch. Any ideas? Thanks for any help you can provide.
--Drake
If you modify your code a bit, you'll see that the values of a single numeric are actually stored as a string, so you're trying to add a string, which Excel isn't happy about. You can try something like this:
Sub test()
Dim namedValue As Variant
namedValue = ThisWorkbook.Names("Foo").Value
ThisWorkbook.Names("Foo").Value = Mid(namedValue, 2, Len(namedValue)) + 1
Debug.Print ThisWorkbook.Names("Foo").Value
End Sub
Which seemed to have the expected results on my test sheet...just make sure you have a named range of "Foo" to test. Obviously tweak to suit your situation, but hopefully it will get you started in the right direction.

How can I read individual lines of a CSV file into a string array, to then be selectively displayed via combobox input?

I need your help, guys! :|
I've got myself a CSV file with the following contents:
1,The Compact,1.8GHz,1024MB,160GB,440
2,The Medium,2.4GHz,1024MB,180GB,500
3,The Workhorse,2.4GHz,2048MB,220GB,650
It's a list of computer systems, basically, that the user can purchase.
I need to read this file, line-by-line, into an array. Let's call this array csvline().
The first line of the text file would stored in csvline(0). Line two would be stored in csvline(1). And so on. (I've started with zero because that's where VB starts its arrays). A drop-down list would then enable the user to select 1, 2 or 3 (or however many lines/systems are stored in the file). Upon selecting a number - say, 1 - csvline(0) would be displayed inside a textbox (textbox1, let's say). If 2 was selected, csvline(1) would be displayed, and so on.
It's not the formatting I need help with, though; that's the easy part. I just need someone to help teach me how to read a CSV file line-by-line, putting each line into a string array - csvlines(count) - then increment count by one so that the next line is read into another slot.
So far, I've been able to paste the numbers of each system into an combobox:
Using csvfileparser As New Microsoft.VisualBasic.FileIO.TextFieldParser _
("F:\folder\programname\programname\bin\Debug\systems.csv")
Dim csvalue As String()
csvfileparser.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
csvfileparser.Delimiters = New String() {","}
While Not csvfileparser.EndOfData
csvalue = csvfileparser.ReadFields()
combobox1.Items.Add(String.Format("{1}{0}", _
Environment.NewLine, _
csvalue(0)))
End While
End Using
But this only selects individual values. I need to figure out how selecting one of these numbers in the combobox can trigger textbox1 to be appended with just that line (I can handle the formatting, using the string.format stuff). If I try to do this using csvalue = csvtranslator.ReadLine , I get the following error message:
"Error 1 Value of type 'String' cannot be converted to '1-dimensional array of String'."
If I then put it as an array, ie: csvalue() = csvtranslator.ReadLine , I then get a different error message:
"Error 1 Number of indices is less than the number of dimensions of the indexed array."
What's the knack, guys? I've spent hours trying to figure this out.
Please go easy on me - and keep any responses ultra-simple for my newbie brain - I'm very new to all this programming malarkey and just starting out! :)
Structure systemstructure
Dim number As Byte
Dim name As String
Dim procspeed As String
Dim ram As String
Dim harddrive As String
Dim price As Integer
End Structure
Private Sub csvmanagement()
Dim systemspecs As New systemstructure
Using csvparser As New FileIO.TextFieldParser _
("F:\folder\programname\programname\bin\Debug\systems.csv")
Dim csvalue As String()
csvparser.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
csvparser.Delimiters = New String() {","}
csvalue = csvparser.ReadFields()
systemspecs.number = csvalue(0)
systemspecs.name = csvalue(1)
systemspecs.procspeed = csvalue(2)
systemspecs.ram = csvalue(3)
systemspecs.harddrive = csvalue(4)
systemspecs.optical = csvalue(5)
systemspecs.graphics = csvalue(6)
systemspecs.audio = csvalue(7)
systemspecs.monitor = csvalue(8)
systemspecs.software = csvalue(9)
systemspecs.price = csvalue(10)
While Not csvparser.EndOfData
csvalue = csvparser.ReadFields()
systemlist.Items.Add(systemspecs)
End While
End Using
End Sub
Edit:
Thanks for your help guys, I've managed to solve the problem now.
It was merely a matter calling loops at the right point in time.
I would recommend using FileHelpers to do the reading.
The binding shouldn't be an issue after that.
Here is the Quickstart for Delimited Records:
Dim engine As New FileHelperEngine(GetType( Customer))
// To Read Use:
Dim res As Customer() = DirectCast(engine.ReadFile("FileIn.txt"), Customer())
// To Write Use:
engine.WriteFile("FileOut.txt", res)
When you get the file read, put it into a normal class and just bind to the class or use the list of items you have to do custom stuff with the combobox. Basically, get it out of the file and into a real class asap, then things will be easier.
At least take a look at the library. After using it, we use a lot more simple flat files since it is so easy, and we haven't written a file access routine since (for that kinda stuff).
http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.fileio.textfieldparser.aspx
I think your main problem is understanding how arrays work (hence the error message).
You can use split and join functions to convert strings into and out of arrays
dim s() as string = split("1,2,3",",") gives and array of strings with 3 elements
dim ss as string = join(s,",") gives you the string back
Firstly, it's actually really good that you are using the TextFieldParser for reading CSV files - most don't but you won't have to worry about extra commas and quoted text etc...
The Readline method only gives you the raw string, hence the "Error 1 Value of type 'String' cannot be converted to '1-dimensional array of String'."
What you may find easier with combo boxes etc is to use an object (e.g. 'systemspecs') rather than strings. Assign the CSV data to the objects and override the "ToString" method of the 'systemspecs' class to display in the combo box how you want with formatting etc. That way when you handle the SelectedIndexChanged event (or similar) you get the "SelectedItem" from the combo box (which can be Nothing so check) and cast it as the 'systemspecs' to use it. The advantage is that you are not restricted to display the exact data in the combo etc.
' in "systemspecs"...
Public Overrides Function ToString() As String
Return Name ' or whatever...
End Function ' ToString
e.g.
dim item as new systemspecs
item.ID = csvalue(1)
item.Name = csvalue(2)
' etc...
combobox1.Items.Add(item)
Let me know if that makes sense!
PK :-)

MS-Access: Replace "bracket"

In one of the ms-access table I work with we have a text field with a set size.
At the end of this field there is some extra code that varies depending on the situation.
I'm looking for a way to remove one of these code but even when the last part is truncated by the field maximum size.
Let's call the field "field" and the code I'm looking to remove "abc-longcode".
If I use the replace SQL function with the string abc-longcode the query will only work when the code is complete.
If I also want my update query (that does nothing but remove this specific code at the end of my field) to work on incomplete codes how would that translate into ms-SQL?
It would have to remove (or replace with "" to be precise) all of the following (example of course, not the real codes):
abc-longcode
abc-longcod
abc-longco
abc-longc
abc-long
abc-lon
abc-lo
abc-l
Obviously I could do that with several queries. Each one replacing one of the expected truncated codes... but it doesn't sound optimal.
Also, when the field is big enough to get all of the code, there can sometime be extra details at the end that I'll also want to keep so I cannot either just look for "abc-l" and delete everything that follows :\
This query (or queries if I can't find a better way) will be held directly into the .mdb database.
So while I can think of several ways to do this outside of a ms-sql query, it doesn't help me.
Any help?
Thanks.
You can write a custom VBA replace method that will replace any of the given cases {"abc-longcode", ... "abc-l"}. This is essentially the same tack as your "several queries" idea, except it would only be one query. My VBA is rusty, but something like:
public function ReplaceCodes(str as string) as string
dim returnString as string
returnString = str
returnString = replace(returnString,"abc-longcode","")
// ... etc...
ReplaceCodes = returnString
end function
I may have gotten the parameter order wrong on replace :)
I would use my own custom function to do this using the split function to get the first part of the string. You can then use that value in the update query.
Public Function FirstPart(thetext As String) As String
Dim ret As String
Dim arrSplitText As Variant
arrSplitText = Split(thetext, "-")
ret = arrSplitText(0)
FirstPart = ret
End Function
Can you use:
Left(FieldX,InStr(FieldX,"abc-")-1)
EDIT re Comment
If there is a space or other standard delimiter:
IIf(InStr(InStr(FieldX, "abc-"), FieldX, " ") = 0, Left(FieldX, InStr(FieldX, "abc-") - 1), Replace(FieldX, Mid(FieldX, InStr(FieldX, "abc-"), InStr(InStr(FieldX, "abc-"), FieldX, " ") - InStr(FieldX, "abc-")), ""))