If you have CSV data that is in and encoding other than ASCII you CAN still use the CSV parser but the results you will need to use “define encoding” on
See this post https://forum.xojo.com/57109-csv-parser-with-utf8-support
If you have CSV data that is in and encoding other than ASCII you CAN still use the CSV parser but the results you will need to use “define encoding” on
See this post https://forum.xojo.com/57109-csv-parser-with-utf8-support
Xojo doesnt support named parameters. And I dont expect they are likely to add it any time soon. But, you can kind of fake it for yourself with a bit of work.
Xojo supports both variadic parameter lists, ones that take an unbounded list of parameter, and a declarative syntax for creating pairs as literals.
You can combine this into faking named parameters.
If you define a method as
Sub foo( paramarray namedParams as Pair )
You can call it like
Foo( "param1":1, "param2":"2" )
and the method will get an array of pairs named namedParams that is composed of pairs. Each pair in the list will, for this example, have its left property holding the name and the right property holding he parameter value.
You can iterate over the array and pull out the relevant values into local variables and the method behaves as if you support “named” parameters like :
dim param1 as integer
dim param2 as integer
for each param as pair in namedParams
select case true
case param.left = "param1"
param1 = param.right.integervalue
case param.left = "param2"
param2 = param.right.stringvalue
else
// here ypou cane do whatever you want
// but I chose to raise an exception
Raise new UnsupportedOperationException
end select
next
You could take this further and add an overload that supports positional parameters like
Sub foo( param1 as integer, param2 as string )
and if you do this you probably want to make sure the named parameter version validates that the types of values for the named versions are consistent with the positional version.
And now you can call with named params or positional params and you can decide whether internally the named one calls into the positional param one or vice versa so you dont have to write the same code twice – just put a different API on it.
Flat out I’ll say Thanks to Xojo for the 2.1 decision to revert the event name changes. Of all the changes that one was probably the hardest one to deal with as there’s no easy way to #if around an event definition or event handler.
Properties may still cause some grief if you start a project in 2019r2 or r2.1 since they don’t retain the “old” values” so going back to an old version can be tricky if you start in 2019r2 or 2.1. At least this can be worked around by starting projects in 2019r1.1 or older and its fairly simple to make it so every project behaves like this by using a template that overrides the normal built in one.
All I can say is WOW !

The Eagles reuniting was the first time I saw hell freeze over
And now I’ve seen it a second time
You’ll see what I mean
All I can say is OMG THANK YOU !!!!!!!!!
Just wait. You’ll see what I mean in the not too distant future.
Great read. May be pay walled. But great read.
Cant say much more than that
It had to happen sooner or later. But now questions about how to do this are appearing. And the answer is “it depends”.
ALWAYS use a copy or have a backup copy of your entire project JUST in case something goes wrong.
IF you have a license that permits you to save as text (Xojo Project) save your project as a text project. You then need to open the single file called projectname.xojo_project
At the very beginning of this file you will see entries like the following :
Type=Desktop
RBProjectVersion=2019.02
MinIDEVersion=20190200
OrigIDEVersion=20190200
Change the number after MinIDEVersion to 20070100 and save. You can now open the project in whatever version you want.
In an XML project you would see
<?xml version="1.0" encoding="UTF-8"?>
<RBProject version="2019r2" FormatVersion="2" MinIDEVersion="20190200">
<block type="Project" ID="0">
Again change the number following MinIDEVersion to 20070100. Make sure you keep the quotes around the value. And save.
Binary is a lot tougher because it is a proprietary format. And to edit that you WILL need a licensed version of Arbed. Once you have that you can open a binary project and select the top entry which represents the project and change the OriginalVersion to 20070100 and the ProjectSavedInVers to 2007.01 and save.
And now you can open your project in old versions again.
Often you’ll hear people say you should use prepared statements to avoid sql injection issues. They’re not wrong. But there can be other reasons to use them.
In some db’s when you create a prepared statement and use it over & over you can avoid a fair amount of a speed hit.
When you initially create a prepared statement many db engines will actually do some work to figure out what the optimal mechanism, or query plan, is to access the data in a table.
And by reusing this over & over you can avoid that computation to determine that optimal query plan.
Not ALL db’s do this, and in some it wont matter if you use a prepared statement because they simply recompute the query plan every time anyways.
But, even if the db engine DOES recompute the query plan over & over you still get all the benefits of avoiding sql injections issues by using them.
I’d say they definitely fall into the category of “best practice”.
With all the hoopla going on about R2 I have been reading some things that are NOT programming related. Not my usual sort of thing to read.
Stuff like this.
And as I read the article I kept saying to myself Uh huh, Yup and Dead On. And the initial observation he made about
Customers switch because the first company let them down. Customer switch because switching is personal. Customers switch because of how you make them FEEL. Maya Angelou said it best: “People will forget what you said, people will forget what you did, but people will never forget how you made them feel.”
and thinking this is so true.
Much of what I’ve read has expressed how disappointed people are talk of the dismissal of their concerns. This has been said in more than one messaging system I participate in and on blogs I read.
How this is all going to fall out for Xojo I have no idea.
But there are many who have expressed they are done and departing as they just can’t take being ignored any longer especially when it puts their businesses at risk.
Sometimes you run into a situation where you want to add functionality to an existing data type. It might be a string, integer, array or perhaps one of the built in classes that you want to add new functionality to.
Exactly how do you do this ?
You can’t just edit the framework and add new methods to the String type.
And that is probably a good thing. Imagine if every user could edit String and add methods to it. There might be a huge plethora of incompatible implementations of String very rapidly.
Since you cannot edit String what can you do ?
Extension methods!
You CAN create a method type that is almost indistinguishable from a method in the base type itself. First I would suggest creating a Module named with a meaningful name. For a Module to add new method to the String data type I would name the module StringExtensions so its very clear what this module contains.
The in this module you can add GLOBAL methods. And each method in the module should have a signature that uses the extends keyword.
I’ll demonstrate. Suppose we wanted to add a new method to String that checks if the first letter of the string is a digit. We’ll name that method IsDigit.
For create a new desktop project.
Add a Module to the project called StringExtensions.
Then add a method to the StringExtensions module and name the method IsDigit.
The parameters for this method should be
extends aString as String
Note the use of EXTENDS. This is the hint to the compiler that this method should be treated as if it were one of the methods in the framework for the String datatype.
The return type for this method should be Boolean.
The code in the method should be
If aString.Trim = "" Then
Return False
End If
If InStr( "0123456789", aString.Left(1) ) > 0 Then
Return True
End If
return false
The finished method should appear like

Then in the Open, or in 2019r2 the Opening event, you can test the new extension method with code like
Dim s As String
s = "abc"
If s.IsDigit Then
Break
End If
s = ""
If s.IsDigit Then
Break
End If
s = "1abc"
If s.IsDigit Then
Break
End If
The first two cases should return false. And the last one should return true.
The only thing to be careful about with extension methods is :
But other than that you can extend most datatypes, even ones in the framework, relatively easily.
2019r2 changes a LOT of things.
Some of the things it changed are subtle and search and replace may NOT be the best approach to updating these.
For instance string method like Mid changed from being a 1 based offset for the starting position to a 0 based offset.
If all you do is change mid to middle you will inadvertently cause an off by one error because the start is now 0 based not 1 based.
For instance
var foo as string = "1234"
var midString as string = foo.mid(2,2)
var middleString as string = foo.middle(2,2)
will give you different results in midString and middleString.
There are many other places where the offsets have changed from 1 based to 0 based so be careful updating your code. Make sure you examine all the parameters being used as well to avoid causing yourself a lot of extra work trying to hunt down those off by one errors.