Qlik Community

QlikView App Development

Discussion Board for collaboration related to QlikView App Development.

Announcements
QlikWorld 2020: Join us May 11 - 14, 2020 in Phoenix, AZ. Register early and save $400. Learn More
Highlighted
hkhkhkhk
New Contributor

for loop crosstable with differing columns

Hi all,

I have been struggling with this issue for a while looking for a solution.

I am trying to load in data from 55 sheets from a total of 289 sheets in an excel spreadsheet.

I need the all columns from the 55 sheets to be transposed into one table using the CrosstTable load function except one column from each sheet to be the qualifier field. However, the qualifier field is not always the same for each sheet. I also want to use a loop as I do not want 55 different load statements in the script.

A few things to consider:

-     The sheets do follow a specific naming convention but they will not change

-     I know the column that is required for each sheet

I have provided an extract of what I am trying below - I think the IF statement is not the right way to go about it. Any help would really be appreciated.

for each vSheet in 'S1', 'D1'  etc

Data:

CrossTable(x, value, 2)

LOAD

          '$(vSheet)' as table,

           if('$(vSheet)' = 'S1', Column1,

                 if('$(vSheet)' = 'D1', Column2, '-')) as datafield,

          *

FROM

[Data]

(ooxml, embedded labels, table is $(vSheet), filters(

Remove(Row, Pos(Top, 3)),

Remove(Row, Pos(Top, 2)),

Remove(Row, Pos(Top, 1)),

Remove(Col, Pos(Top, 1))

));

next;

3 Replies
vinieme12
Esteemed Contributor II

Re: for loop crosstable with differing columns

This will not work, because you are only renaming an existing column in the first line with the IF Statement you are not actually changing the Order in which the columns are loaded into Qlikview

Example

Load

if(a='1',a) as newname

,b,a,c,d      /// because * will still load all the columns

;

I would suggest creating an Excel macro to re-arrange the columns in the workbook itself.

Or

Create variables with list of fields in the Order you want to load them

Example

vSheet1Fields = Field3,Field1,field2,field4;

vSheet2Fields = Field4,Field1,field2,field3; and so on

and use the if statement to use the fieldlist depending on the sheetname   (/// This would still be a pain considering the number of sheets you have)

Example;

Load

if(Sheet1 , $(vSheet1Fields))     //// You got the point , right?


Re: for loop crosstable with differing columns

please provide some sample data and your expected result as well.

thanks

regards

Marco

MVP
MVP

Re: for loop crosstable with differing columns

Yes you approach should work out. Your doubts around the IF is right - there is a better way to handle it.

I would suggest using a table - either inline or from a spreadsheet or CSV-file. The following code has not been tested - just write out from the top of my head. Anyways it gives you an indication of an approach that should work.

Sheets:

LOAD * INLINE [

Sheet,Col

Sheet1, ColC

Sheet6, C2

SheetB, AAA

....

];

nRows = NoOfRows('Sheets');

vColList ='';

FOR i=1 TO nRows

    vSheet = Peek('Sheet',i,'Sheets');

    vCol = Peek('Col',i,'Sheets');

  

    // pad the colums in the columnlist with @ before and after the column name, needed for correct Match later.

    vColList = vColList & If(i=1,'',',') & Chr(39) & '@' & vCol & '@' & Chr(39) ;

    Temp_Data:

    CrossTable(x, value, 2)

    LOAD

          '$(vSheet)' AS Table,

          $(Col) AS Dim,

          *    // Will also load the $(Col) as a data column that turns into rows, remove them in the final load

    FROM

          [Data.xlsx] (ooxml, embedded labels, table is $(vSheet), filters(

              Remove(Row, Pos(Top, 3)),

              Remove(Row, Pos(Top, 2)),

              Remove(Row, Pos(Top, 1)),

              Remove(Col, Pos(Top, 1))

          ));

NEXT

// Exclude all the rows that were added for the double load of the Col (attribute column)

Data:

LOAD * RESIDENT Temp_Data

WHERE Match( '@' & x & '@' , $(vColList))=0 ;

DROP TABLE Temp_Data;

Hope this makes sense - if not just ask me to clarify...