Incrementing the value of a variable by one - vba

Incrementing the value of a variable by one is often achieved in other basic dialects in ways like
myreallylongandawkwardvariable ++
or
inc(myreallylongandawkwardvariable)
Is the only way to achieve this in VBA to code like this?
myreallylongandawkwardvariable = myreallylongandawkwardvariable +1

That is the only standard way to increment a variable with VBA.
If you really want to, you can create a custom procedure:
Sub Increment(ByRef var, Optional amount = 1)
var = var + amount
End Sub
Then you can do the following:
Increment myreallylongandawkwardvariable 'Increment by 1
Increment myreallylongandawkwardvariable, 5 'Increment by 5

#DanBaeckström, that is Not strictly correct.
If you call a procedure simply by its name, as in:
Increment myreallylongandawkwardvariable
you don't use parentheses.
But, if you precede this procedure call with the keyword "Call", as in:
Call Increment(myreallylongandawkwardvariable)
you MUST use parentheses.

Related

Randomly insert 1 of 3 declared variables

I have three variables that are declared and have an integer value assigned to them.
I am trying to randomly assign the integer value to a field in an UPDATE statement, but get an error.
This is statement I am trying to execute:
FOR user_record IN (SELECT * FROM users_to_add) LOOP
UPDATE
customer."user"
SET
primary_site_id = ({site_GRO, site_WHS, site_SHR}[])[ceil(random()*3)],
WHERE
userid = (SELECT userID FROM customer.user
WHERE emailaddress=user_record.email_address);
END LOOP;
I am getting:
SyntaxError: syntax error at or near "{"
This same format works if the value being randomly selected is a string but since these are variables, the inside curly brackets can't be enclosed in quotes.
Use an ARRAY constructor instead of the (invalid) array literal.
(ARRAY[site_GRO, site_WHS, site_SHR])[ceil(random()*3)]
However, a set-based solution is typically more efficient than looping:
UPDATE customer."user" u
SET primary_site_id = CASE trunc(random()*3)::int
WHEN 0 THEN site_gro -- your variables here
WHEN 1 THEN site_whs
WHEN 2 THEN site_shr
END
FROM users_to_add ua
WHERE u.userid = ua.email_address;
Should achieve the same. Works inside a PL/pgSQL block or as standalone SQL DML command (then you need to interpolate variable values yourself).
A single multi-row UPDATE is much cheaper than many updates in a loop.
trunc() is slightly more correct than ceil(), as random() returns a value in the domain [0,1) (1 excluded). It's also faster.
And a CASE construct is substantially faster than building an array just to extract a single element from it.
Asides:
Avoid reserved words like user as identifiers. Always requires double-quoting, and can lead to confusing errors when forgotten.
Also avoid random capitalization in identifiers. This goes for SQL as well as for PL/pgSQL. See:
Are PostgreSQL column names case-sensitive?
Perhaps you can try splitting the index and array out into their own vars?
FOR user_record IN (SELECT * FROM users_to_add) LOOP
a := ARRAY[site_GRO, site_WHS, site_SHR];
i := ceil(random()*3);
UPDATE
customer."user"
SET
primary_site_id = a[i]
WHERE
userid = (SELECT userID FROM customer.user WHERE emailaddress=user_record.email_address);
END LOOP;

Defining the (alias) name of a field

I've been looking over some code in an old Classic ASP system of ours that builds its own SQL within the stored procedure and then executes it {shudders}.
Several of the SELECTion lines contain an assignment, similar to:
SELECT
my_field = CASE WHEN value = whatever THEN 1 ELSE 0 END
...
Is there any difference (or anything I need to be aware of) between this and using a standard AS alias?...
SELECT
CASE WHEN value = whatever THEN 1 ELSE 0 END AS my_field
...
No, the following code is all synonymous:
SELECT one = 1;
SELECT 1 one;
SELECT 1 AS one;
SELECT 'one' = 1; --this is deprecated, don't use it.
Which you use (apart from the last), is normally down the preference. Personally, I use AS. One reason is I can then easily tell queries that return datasets, and those that assign values to variables a part.
The 2 examples that you have given are identical. However, when you go through the old code you might also find a variant with an # sign before my_field, like this:
SELECT
#my_field = CASE WHEN value = whatever THEN 1 ELSE 0 END
In this case a varable called #my_field is assigned a value, but nothing is SELECTed. This you can not rewrite to the other syntax using AS #myfield.

Procedure not automatically generating number as coded

My code is:
Private Function CreateID() As Integer
'finds the current highest ID
For Each row As DataRow In MedDT.Rows
If row.Item("MedicineID") > CreateID Then
CreateID = row.Item("MedicineID")
End If
Next
'returns a value for eventID that is unused as its higher then the current highest
Return CreateID
End Function
It should automatically generate a number which is one higher than the highest value in the DataTable but for some reason it isn't working
I call the procedure in the Form_Load procedure to fill a text box.
You are scanning a DataSet for the highest MedicineID number but you forgot to increment that value by 1 before returning, just change your return statement to:
Return CreateID + 1
You should just mark the ID column as IDENTITY and forget about that trivial thing though
Just to add to what Machinarius has said, Data Table itself has an auto Increment option on a column
DataColumn.AutoIncrement = true;
DataColumn.AutoIncrementSeed = 1;
DataColumn.AutoIncrementStep = 1;
so if you are not loading the data from a database you could also use this option.

db2 stored procedure if else variable comparison

I am trying to compare a variable in db 2 sp using like, however it always goes to the else part of the statement, can someone correct the syntax here..here is the part of the code
do
IF(#variable like '%abc') THEN
set #anotherVariable='abc';
ELSEIF (#variable like '%def') THEN
set #anotherVariable='def';
ELSEIF (#variable like '%def') THEN
set #anotherVariable='def';
ELSE
set #anotherVariable='xyz';
END IF;
END FOR;
This code is part of a cursor, query always returns 1 value, however my comparison is not working(incorrect syntax?), it always goes to the last else as if it never was able to match. I know that value is there but its not comparing in this manner...Thanks
Are you writing SQL-PL code? Because variables are referenced directly by its name, not preceded by the '#' sign.
Another thing is that you are using the like operator outside a query. 'Like' is not a function, it is a predicate: http://pic.dhe.ibm.com/infocenter/db2luw/v10r5/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0000751.html
Instead, you can use a 'case' in the select and then return the corresponding value. In that way you do not need to do an 'if-else': http://pic.dhe.ibm.com/infocenter/db2luw/v10r5/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0023458.html

Writing the content of a local variable back to the resultset column?

Is it possible, by using a stored procedure, to fetch an integer column value from resultset into a local variable, manipulate it there and then write it back to the resultset's column?
If so what would the syntax look like?
Something along the following lines should do the trick.
DECLARE #iSomeDataItem INT
SELECT #iSomeDataItem = TableColumName
FROM TableName
WHERE ID = ?
--Do some work on the variable
SET #iSomeDataItem = #iSomeDataItem + 21 * 2
UPDATE TableName
SET TableColumName = #iSomeDataItem
WHERE ID = ?
The downside to an implementation of this sort is that it only operates on a specific record however this may be what you are looking to achieve.
What you are looking for is probably more along the lines of a user-defined function that can be used in SQL just like any other built in function.
Not sure how this works in DB2, but for Oracle it would be something like this:
Create or replace Function Decrement (pIn Integer)
return Integer
Is
Begin
return pIn - 1;
end;
You could use this in a SQL, e.g.
Select Decrement (43)
From Dual;
should return the "ultimate answer" (42).
Hope this helps.
Thanks for the replies, i went another way and solved the problem without using a procedure. The core problem was to calculate a Date using various column values, the column values ahd to to converted to right format. Solved it by using large "case - when" statements in the select.
Thanks again... :-)
Why not just do the manipulation within the update statement? You don't need to load it into a variable, manipulate it, and then save it.
update TableName
SET TableColumnName=TableColumnName + 42 /* or what ever manipulation you want */
WHERE ID = ?
also,
#iSomeDataItem + 21 * 2
is the same as:
#iSomeDataItem + 42
The function idea is an unnecessary extra step, unless most of the following are true:
1) you will need to use this calculation in many places
2) the calculation is complex
3) the calculation can change