mjpedreira1
8th October 2012, 16:44
Hello,

I need to work with an array of clients, but the array have variable long...
I would like to define next variable

domain tccuno client.array(number_client)

where number_client is not an fixed amount; sometimes my array have 2 clients, and sometimes more...

With last definition, I get error:
"Only constants allowed for substring"

Regards,
María

BaanDeveloper
8th October 2012, 17:42
Is there a known maximum amount of sub strings that you will work with? If so, why can't you size the sub array for the maximum, and then if you need to know how many you are using - create a 2nd array to store a long in an array of equal size and with a sub array that contains a long representing the count of used strings in the source array.

BaanInOhio
8th October 2012, 18:12
You need to use dynamic arrays. Define your initial array as BASED with 1 position for each dimension. Use alloc.mem to redefine (increase) the size of the array as you need more space. You must call free.mem at the end to give the memory back to the OS. I normally use two counter variables for dynamic array handling = the maximum number of rows for the array (size of last allocation) and the row number that was most recently inserted. When your current row exceeds the max rows variable (increment before you store data), call alloc.mem again to increase the array size.


string cuno.string(1,1) BASED
long array.max, array.cur

array.max = 20
array.cur = 0
alloc.mem(cuno.string, 8, array.max) | 20 strings of 8 characters.

:
:

array.cur = array.cur + 1
if (array.cur > array.max) then
array.max = array.max + 20
alloc.mem(cuno.string, 8, array.max)
endif
cuno.string(1,array.cur) = "data"
:
:

free.mem(cuno.string) | Called when you are done with the array


You can always add rows and even new columns on the fly without loss of existing data. You can't increase the size of a string in a dynamic array without losing data - so you have to save existing data in a temporary dynamic array, expand the current array width, reload from the temporary array.

Refer to help for alloc.mem, free.mem and dynamic array general info.

mjpedreira1
8th October 2012, 19:17
Thanks for your code.
I´ve implemented your code, but, If I want to work with the string cliente I have an error in the function desbloqueamosClientes():

string cliente(1,1) BASED
long array.max, cliente.actual


clientesBloqueados("30000000433")
desbloqueadmosClientes()


function clientesBloqueados(string hgt(11))
{
| string cliente(1,1) BASED
domain tccuno cl
| long array.max, cliente.actual

array.max = 20
cliente.actual = 0
alloc.mem(cliente, 6, array.max) | 20 strings of 8 characters.

select tppdm740.cuno:cl
from tfcmn040, tppdm740 , tccom010
where tppdm740.cprj=tfcmn040.cprj
and tfcmn040.idhg=:hgt
and tccom010.cuno=tppdm740.cuno
and tccom010.cnpa=3
group by tppdm740.cuno
selectdo
cliente.actual = cliente.actual + 1

if (cliente.actual > array.max) then
array.max = array.max + 20
alloc.mem(cliente, 8, array.max)
endif

cliente(1,cliente.actual) = cl

selectempty
endselect

| free.mem(cliente) | Called when you are done with the array
}

function desbloqueamosClientes()
{
domain tccuno hola

select tccom010.nama
from tccom010
where tccom010.cuno = :cliente(1,1)
selectdo
hola=hola
endselect


}

mjpedreira1
8th October 2012, 19:28
The message error is
"Substring for non-string column not allowed"

Thanks,
María

BaanInOhio
8th October 2012, 20:10
The message error is
"Substring for non-string column not allowed"

Thanks,
María

You have to declare the string array width (number of characters) to cover the number of characters that you expect to add (11):

alloc.mem(cliente, 11, array.max) | 20 strings of 11 characters.


Make sure that you use the 'free.mem' at the end of processing to give it back to the OS for other uses.