Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

after scanning two arrays, error doing arithmetic operation

Status
Not open for further replies.

fanlinux90

Programmer
Oct 31, 2022
22
CO
when trying to go through two arrays (daysft and daysf),both arrays have stored numbers When doing the return calculation I get an error

are local variables holidayst, holidays, cvalue, return
cvalue = 0
return = 0

select providers

scan
cvalue = vendors.vpurchase
Messagebox(allt(Str(cvalue)))
FOR i = 0 TO ALEN(daysft ,1) STEP 1
holidayst = daysft
FOR i = 0 TO ALEN(daysf,1) STEP 1
holidays = daysf
return=((cvalue/(holidayst))*(holidays))
Messagebox(allt(Str(return)))
ENDFOR
ENDFOR
end scan

I am trying to loop daysft save it in holidayst, loop daysf save it in holidays,
to then do the calculation ((valuec/(holidaysst))*(holidays)) and save it in return


I get an error in the line return=((cvalue/(holidaysto))*(holidays)) the data types do not match
 
with vartype I check the arrays Messagebox(vartype(diasft)) and Messagebox(vartype(diasf)).with vartype I check the arrays
returns L for both,
 
fill the arrays with a for

FOR i = 0 TO ALEN(diasft,1) STEP 1
daysf = count

ENDFOR
 
I see several issues.

First, using the same variable (i) for both nested loops means you're going to jump around in the outer loop. Use a different variable for the inner loop.

Second, you can't just assign a whole array that way. If you have an array named daysft, then you can access its contents as daysft[1], daysft[2], and so on. With the outer loop variable i, you can use daysft[m.i].

I don't understand your explanation of what you're trying to do, but if you just want to know how many items total (assuming no overlap between the two arrays), just use ALEN() to get the length of each and add the two together:

Code:
nTotal = ALEN(daysft,1) + ALEND(daysf, 1)

If that's not what you're trying to do, then show up what the contents of the arrays look like and what result you want.

Tamar
 
You mainly have a wrong idea about addressing array elements.

As Tamar said arrays are addressed with index, the array name alone can be used to address array element 1 only, if you read an array, and if you write arrayname=value you store that value into all elements. The former is slightly unusual, the latter very unusual, but to address any specific element you need [tt]arrayname[index][/tt] or in 2d arrays [tt]arrayname[index1,index2][/tt].

There is a foreach loop type which copies array elements one by one into the same variable and then you can work with that in the loop body, but that's readonly, changing that variable dooes not change array elements, IIRC in PHP that works this way. But before you go to Foreach usage, I'd suggest you get used to inde addressing. By the way, not database table index, just element index as in mathematical notation typically as subscript.

Step by step:
1. creating an array can be done with DIMENSION (also redimension an existing array), but also with LOCAL ARRAY. And, well, last not least an SQL query can be done INTO ARRAY.
Code:
DIMENSION myarray1[10]
LOCAL ARRAY myarray2[10]
LIST MEMORY LIKE my*
The difference is DIMENSION creates an array with private variable scope, LOCAL ARRAY - obviously - with local variable scope. Not ultra important for now

2. As you see from LIST MEMORY all elements start as .F., that's a default value for all VFP variables.
3. Setting all elements by only using the array name:
Code:
LOCAL ARRAY myarray3[10]
myarray3 = 0
myarray3[1]=1
LIST MEMORY LIKE myarray3
You see the first element is 1, all other elements are 0 now.
Code:
? myarray3
this prints 1, as using the array name for reading it you always read the first element only. A VFP array also is not an iterator that will automatically skip to the next element when you read it. It's a damn simple array with integer indexed array elements, also not an associative array where array elements can be addressed by a key that can be a string, for example. It's an array, a simple array. The first element addressing shortcut can be slightly helpful, but it is just that, not getting to all elements one by one. You could simply concentrate on adressing with index and always use myarray[1] for that.

4. for each loops - reading throuogh an array can be done with this loop type where you copy over each array element
Code:
For each element in myarray3
  ? element
EndFor
If you set element=42, you don't set some array element this came from to 42, too. element really is its own normal single scalar value variable, into which for each copies element by element. But the array name itself does not work as an iterator.

Chriss
 
All that said, iterations in VFP are usually done on cursors, arrays are not the best to use. One big advantage of cursors (or actual tables,DBFs) is that now you iterate rows of data with every row having named fields. That's like having a number of reccount associative arrays, where indeed you can address the elements by the key alone, i.e. a fieldname is sufficient to read the field value of a "current" record. Which is a concept you should know or learn. The language element for cursor loops is SCAN...ENDSCAN loops.

I'll not go into scn loops, but as I touch on reading fields by name only you have to know one consequence of that:
Field names could be the same as variable names, no matter if scalar variables or arrays, local or private or public or whatever scope. As VFP is mainly a database field (aka as a column of a table) have priority over variables, so a field of the same name "masks" a variable that also has that name. Masking measn it becomes inaccessible by it's normal name. There is a directer way of meaning variables you can easily memorize by thinking of m as memory, so m.varaiblename always addresses a varriable of that name.

Which means you could prefix all your variable usage with m.

That's why Tamar mentioned daysft[m.i] for using the variable i as index. The full consequence would be reading m.daysft[m.i], but if you write to a variable you can write i=42 or daysft[1]=1, that's not effected by the masking of variables by fields, as it's write access, you assign values and you can't change a field by fieldname=value, that needs UPDATE-SQL or REPLACE or some more, but while a field is easily read by its name only, it's still not the same as a variable.

Chriss
 
By the way, all this means you did not - as the title says - scan two arrays.

Chriss
 
fanlinux90 said:
I am trying to loop daysft save it in holidayst, loop daysf save it in holidays,
There's ACOPY to do that.
But it makes no sense to me, to copy the arrays for each record of providers. The arrays don't change and if you copy them over and over again you just recreate the same copy you already have.
You seem to me like yet another troll.

Chriss
 
Hi,

You may scan two arrays but the syntax of your code must be correct - see below. Furthermore I recommend not to use VFP reserved word as variables (e.g. RETURN), You also may want to adopt the usual naming convention for fields, variables etc.

Code:
LOCAL liHolidayst as Integer, liHolidays as Integer, liValue as Integer, lnReturnValue as Number

liValue = 0
lnReturnValue = 0

SELECT providers

SCAN 
	liValue = vendors.vpurchase

		WAIT WINDOW + TRANSFORM(liValue) TIMEOUT .5

	FOR i = 1 TO ALEN(daysft, 1) STEP 1

		liHolidayst = daysft[i, 1]
		
		FOR j = 1 TO ALEN(daysf, 1) STEP 1

			liHolidays = daysf[j, 1]
			
			lnReturnValue = liValue / liHolidayst * liHolidays
			
			WAIT WINDOW TRANSFORM(lnReturnValue) TIMEOUT .5
		ENDFOR
	ENDFOR
ENDSCAN

Are you aware that your intended code will generate 75 * 75 = 5625 returned values - since both arrays have 75 elements. It will take +/- 45 min with .5 sec as TIMEOUT to finish. I replaced the MESSAGEBOX with the WAIT WINDOW in order to avoid to have to hit the OK Button 5625 times.

If I misunderstood your intention, please apologize and return a more detailed explanation.

hth

MarK
 
MarK, as you take his code serious, the last return value he computes is
returnvalue=((cvalue/(daysft[ALEN(daysft,1),1]*daysf[ALEN(daysf,1),1])

It makes no sense to go through all elements and not accumulate them with a count or sum or whatever, if all you end up with to return is only about the last array elements.
There also is missing a RETURN returnvalue.

We don't even know what the arrays are and whether this all makes sense at all is very questionable, that's also why I limited my help about showing how arrays work.

If he wants to count fridays, saturdays and sundays as in his previous question and has made one further step to have arrays of them, then I wonder why there are two arrays instead of three, but that aside, it's far simpler to SELECT Count(*) FROM sometable or CALCULATE SUM ...TO variable or COUNT .... TO variable than going through hoops with creating arrays and pocessing them.

Anyway, it's not the first time someone trolls this forum, who's likely questioning the existence of FoxPro for how legacy a language it is, but really does lack evidence of programming with anything else in a more modern way. From time to time something like that shows through. I mentioned iterators, like lists, which you can actually iterate just by addressing them over and over. It could just be a coincidence he hits some concept like this, but overall I don't trust this to be of any relevance.

Chriss
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top