Iterations – or loops – are constructions where a set of statements are executed zero or more times, until some condition is met. They are very common in all programming languages, and QlikView scripting is no exception.
First of all, the Load statement is in itself a loop: For each record in the input table, the field values are read and appended to the output table. The record number is the loop counter, and once the record is read, the loop counter is increased by one and the next record is read. Hence – a loop.
But there are cases where you want to create other types of iterations – in addition to the Load statement.
For - Next Loops
Often you want a loop outside the Load statement. In other words; you enclose normal script statements with a control statement e.g. a "For…Next" to create a loop. An enclosed Load will then be executed several times, once for each value of the loop counter or until the exit condition is met.
The most common case is that you have several files with the same structure, e.g. log files, and you want to load all of them:
For eachvFileNamein Filelist ('C:\Path\*.txt') Load *, '$(vFileName)' asFileName From [$(vFileName)]; NextvFileName
Another common case is that you already have loaded a separate table listing the files you want to load. Then you need to loop over the rows in this table, fetch the file name using the Peek() function, and load the listed file:
ForvFileNo = 1 to NoOfRows('FileListTable') LetvFileName = Peek('FileName',vFileNo-1,'FileListTable'); Load *, '$(vFileName)' asFileName From [$(vFileName)]; NextvFileNo
Looping over the same record
You can also have iterations inside the Load statement. I.e. during the execution of a Load statement the same input record is read several times. This will result in an output table that potentially has more records than the input table. There are two ways to do this: Either by using a While clause or by calling the Subfield() function.
One common situation is that you have a table with intervals and you want to generate all values between the beginning and the end of the interval. Then you would use a While clause where you can set a condition using the loop counter IterNo() to define the number of values to generate, i.e. how many times this record should be loaded:
Another common situation is that you have a list of values within one single field. This is a fairly common case when e.g. tags or skills are stored, since it then isn’t clear how many tags or skills one object can have. In such a situation you would want to break up the skill list into separate records using the Subfield() function. This function is, when its third parameter is omitted, an implicit loop: The Load will read the entire record once per value in the list.
Actually no because I do not want to chose the min value.
Let me try to explain again:
I have a distribution Center that fulfill some store ( in the real case is 3 for 303 stores but I am tryinf to make it simple to make the logic with your help )
Distributuion Center
STORE
X1
S1
X1
S3
X2
S2
I have a demand to supply the Stores but need to see if the Distribution Center has capacity.
*Here it is an example with random numbers.
I have how much we have in the CD of each SKU.
If Stock CD > What I need then it is available.
If Stock CD = 0, then out of stock.
Else: Not available.
SKU
Distributuion Center
SKU&CD
Need
Stock CD
Status
Send Available
A
X1
A/X1
7
15
Available
7
A
X2
A/X2
20
15
Available
0
B
X1
B/X1
30
20
Not available
20
B
X2
B/X2
7
20
Not available
7
C
X1
C/X1
20
0
Out of stock
0
C
X2
C/X2
30
0
Out of stock
20
That is fine the logic for me.
Note that now we have the Key SKU Store.
Then I can do an apply map because I know what are the CD that fullfil the Store.
*Random numbers again, they are not related.
SKU
STORE
SKU&STORE
CD
KEY
Buffe Old
BufferNew
Status CD
Increase
A
S1
A/S1
X1
A/X1
5
10
Available
5
A
S2
A/S2
X2
A/X2
3
8
Available
-
A
S3
A/S3
X1
A/X1
3
8
Available
-
B
S1
B/S1
X1
B/X1
5
10
Not available
5
B
S2
B/S2
X2
B/X2
3
8
Not available
-
C
S1
C/S1
X1
C/X1
5
10
Out of stock
5
C
S2
C/S2
X2
C/X2
3
8
Out of stock
-
In the cases that it is available it is ok, I have the capacity to attend the demand.
My issue is:
The cases when it is not available I have an amount that I can distribute to the stores but not 100%
SKU
Distributuion Center
SKU&CD
Need
Stock CD
Status
Send Available
B
X1
B/X1
30
20
Not available
20
B
X2
B/X2
7
20
Not available
7
TOTAL
37
20
I have the need to send 37 but only 20 in my CD.
Then I need to fullfill it to the stores and Skus according to the keys.
My question is if I can do a looping to fullfill it till the 20 based on a criteria.
I need to set up upload of daily data from remote web address ending with ...=YYYYMMDD
I need data for 2 months day by day.
So far I have this :
SET vStartDate = 2017.03.01;
SET vEndDate = 2017.04.30;
SET DateFormat ='YYYY.MM.DD';
Table:
LOAD Date(StartDate+IterNo()-1) as Date
While StartDate+IterNo()-1 <= EndDate;
LOAD
Min(StartDate) as StartDate,
Max(EndDate) as EndDate
Inline [
StartDate, EndDate
'$(vStartDate)', '$(vEndDate)'
]; // Decided to fill in table with dates and then parse it to address.
for vDateNr =1 to NoOfRows('Table')
let vDate = Peek(Num(Date#('Date'),'YYYYMMDD'),vDateNr-1,'Table');
Rates:
LOAD
DATE('$(vDate)') as Date,
Property,
Price
FROM
[http://.....=$(vDate)]
(txt, utf8, no labels, delimiter is '\t', msq);
NEXT vDateNr
Your solution should work. I cannot see any problem with it.
But I would probably go for a simpler solution, like
For vDateNr = 0 to 60 Step -1 Let vDate = Text(Date(Today()-vDateNr,'YYYYMMDD')); Load Date#('$(vDate)','YYYYMMDD') as Date, Property, Price From [http://.....=$(vDate)] (txt, utf8, no labels, delimiter is '\t', msq); Next vDateNr
There are 32 rows for Property, and Price cells values per date Nr1 .
So it fills only First 32 rows with 'date Nr1' and data For Property an Price and then fills rest with dates (one row of each) and leaving Blank values for Property and Price