QLikView VBScript create field in PivotTable - vb.net

I create a Pivot Table with a VBScript in QLikView:
sub cleanUp()
set sheet = ActiveDocument.Sheets("Summary")
set summaryTable = sheet.CreatePivotTable
summaryTable.addDimension "Product Group Desc"
summaryTable.addDimension "Product Type Desc"
summaryTable.addDimension "Product Sub Group Desc"
summaryTable.addDimension "Country"
summaryTable.addDimension "ZoneMgrName"
summaryTable.addExpression "Sum({<[Fiscal Year]={$(vCurrentYear)}>}
[Sales Amount])"
set props = summaryTable.getProperties
set expr = props.Expressions.Item(0).Item(0).Data.ExpressionVisual
expr.Label.v = "Expenses $(vCurrentYear)"
expr.NumAdjust = 1 'center
expr.LabelAdjust = 1 'center
summaryTable.SetProperties props
end sub
In addition I would like to create new fields used as dimensions. These fields are not in my QLikView document so far. The value for these fields is linked to the value of other fields. Say I have a field Country in my Pivot Table. I would like to add a new Field "Area" which contains the name of the area which the country belongs to. So that the values for the field would be the return value of a function which returns the area for a given country.

It depends on how your "lookup" data is accessed (whether it resides in your QlikView document, or is external), but you are free to add calculated dimensions to your pivot via the addDimension method. For example:
summaryTable.addDimension "=if(Country='France', 'EU', 'non-EU')"
You can use any normal expression that can return meaningful values for your dimension.
If you wish to name the dimension, you can use addDimension's return value as follows:
dimensionNum = summaryTable.addDimension("=if(Country='France', 'EU', 'non-EU')")
set tableProperties = summaryTable.getProperties
set calcDim = tableProperties.Dimensions.Item(dimensionNum-1)
calcDim.Title.v = "Area"
summaryTable.SetProperties tableProperties

Related

Excel VBA Error: 1004 Method 'Range' of object '_Worksheet' Failed when Selecting the Range of a Variables Value

My problem:
When trying to Set Table = cSheet.Range(brand_edit) (brand_edit is a variable with the value of a table name) I get Run-time error '1004': Method 'Range' of object '_WorkSheet' failed.
I think it is because I am trying to find the range of a variable's value and I can't think of a way to fix this.
More Info:
I am making a userform that allows the user to grab an Item ID from a Data Sheet in excel and fill a table/item list with the data from the row the Item ID leads.
I have setup a combobox that grabs my table of contents (the Brands) from the Data Sheet (I made it into a table and used the table as the RowSource). I then setup another combobox that displays the Item ID's from the selected Brand. When you select a particular ID I am trying to get it to grab the data from the row in the table that that Item ID leads.
Each Brand has a table tied to it I use some funky replacing to get it to match the table naming scheme. I use these tables as flexible ranges (these tables will change over time so I need to account for that). The item ID's lead the rows and each row has information about the item (cost, description, etc.)
If there are better ways to do any of these things, I am open to ideas.
These are some questions I viewed to try to solve this:
This one introduced me to the code for this and I tried factoring to my use case and I got errors.
Excel VBA - select, get and set data in Table
Public brand_edit As String
Private Sub cmbItemID_Change()
Dim cBook As Workbook
Dim cSheet As Worksheet
Dim ItemID As String
Dim Brand_Table As String
Dim test As String
Dim i As Long
Dim Table As ListObject
Set cBook = ActiveWorkbook
Set cSheet = cBook.Sheets("Gen. Info")
ItemID = cmbItemID.Value
Brand_Table = brand_edit
MsgBox Brand_Table
Set Table = cSheet.Range(brand_edit).Select
For i = 1 To Table.ListRows.Count
If Table.ListColumns(1).DataBodyRange.Rows(i) = ItemID Then
MsgBox ItemID
End If
Next
MsgBox test
End Sub
Public Sub cmbItemID_DropButtonClick()
'funky replacing
Dim brand As String
brand = cmbBrand.Value
brand_edit = Replace(brand, " ", "_")
brand_edit = Replace(brand_edit, """", "")
brand_edit = Replace(brand_edit, "-", "")
brand_edit = Replace(brand_edit, "__", "_")
brand_edit = LCase(brand_edit)
cmbItemID.RowSource = brand_edit
End Sub
There is a better way to Synchronize ComboBoxes! No coding!
Both ComboBoxes have the same dataSetting settings. They set the same value in the shared LinkedCell.
1. BoundColumn
2. LinkedCell
3. ListFillRange
But we change their display setting to give the user a different view.
1. ColumnCount
2. ColumnWidths
3. ListRows
4. ListWidth
You can not directly set a the ListFillRange to a Table. The workaround is to create a Define a Name and set the ListFillRange the new name.
ListFillRange -> Products -> Table1
So I fixed the problem. What was causing it was I was referencing the wrong sheet (aka Gen. Info). How I fixed it was this:
Set dSheet = cBook.Sheets("DATA")
Set Table = dSheet.Range(brand_edit)
Of course once one problem is fixed another one appears. So I am currently working to fix that one.
This post after reading it a number of times (a few last night before posting this and then a couple times this morning) I finnaly got what it was saying and helped me fix this problem. VBA method 'range of object' _Worksheet failed suddenly coming up when running code?
Hopefully this is more useful.
Place getRowSource in a public module. It'll be easier to test and expand.
Public Function getRowSource(brand As String) As String
brand = Replace(brand, " ", "_")
brand = Replace(brand, """", "")
brand = Replace(brand, "-", "")
brand = Replace(brand, "__", "_")
brand = LCase(brand)
getRowSource = brand
End Function
In this way, you can test your rowsource logic in the Immediate Window
If cmbItemID's RowSource is the table that you want to reference then cmbItemID' s ListIndex is it the row that you want to reference.
Dim itemIndex As Long, brand_edit As String
brand_edit = getRowSource(cmbBrand.Value)
itemIndex = cmbItemID.ListIndex
With cSheet.ListObjects(brand_edit)
TextBoxListPrice.Value = DataBodyRange(itemIndex, 1)
TextBoxListCost.Value = DataBodyRange(itemIndex, 2)
TextBoxNotes.Value = DataBodyRange(itemIndex, 3)
TextBoxSpecs.Value = DataBodyRange(itemIndex, 4)
TextBoxDescription.Value = DataBodyRange(itemIndex, 5)
End With

Base data sheet form will not display calculated Field

I have a Data Sheet form which has a calculated field column. However the field will not display even though it has the correct value. The field in question is "numRisk":
Sub Calculate_Risk (Form As Object)
Dim OrderPrice, IfDonePrice, TotBrSymComm, BrComm, Risk As Double
Dim Symbol As String
Dim IntRateMult, noContracts As Integer
If MinTick = 0 OR Rate = 0 Then
Exit Sub
End If
Symbol = RTrim(Form.getByName("txtSymbol").CurrentValue)
If Symbol = "" Then
Exit Sub
End If
OrderPrice = Form.getByName("fmtOrder_Price").CurrentValue
IfDonePrice = Form.getByName("fmtIf_Done_Price").CurrentValue
noContracts = Form.getByName("fmtNo_Contracts").CurrentValue
If NOT USIntRates Then
Risk = ABS(OrderPrice - IfDonePrice) / MinTick
Else
Risk = ABS(OrderPrice\1 - IfDonePrice\1) * MinTick
IntRateMult = IIf(Symbol = "FV" OR Symbol = "TU",400, 200)
Risk = ABS(Risk - IntRateMult * ABS(OrderPrice - OrderPrice\1
IfDonePrice + IfDonePrice\1))
End If
Risk = Risk * MinTickVal / Rate
TotBrSymComm = BrSymComm + BrSymCommAud
BrComm = IIf(TotBrSymComm = 0, BrCommission, BrSymCommAud + BrSymComm/Rate)
Risk = noContracts*(Risk + BrComm * 2)
Form.getByName("numRisk").Value = Risk
End Sub
The subroutine is called from the following routine which is triggered when the form is loaded:
Sub FromListForm(Event as Object)
Dim Form As Object
Dim TodaysDate As New com.sun.star.util.Date
Dim CurrDate As Date
Form=Event.Source.getByName("MainForm_Grid")
Form.RowSet.first()
Do Until Form.RowSet.isAfterLast()
Get_Contract(Form)
Get_Broker_Comm(Form)
Calculate_Risk(Form)
If isEmpty(Form.getByName("OrderDate").Date) Then
CurrDate = Date()
TodaysDate.Day = Day(CurrDate)
TodaysDate.Month = Month(CurrDate)
TodaysDate.Year = Year(CurrDate)
Form.getByName("OrderDate").CurrentValue = TodaysDate
End If
Form.RowSet.next()
Loop
Form.RowSet.last()
End Sub
Also is there a more efficient method to cycle through the rows? As this seems so slow I can see the row pointer moving down the table as each row is processed.
If I understand correctly, you're trying to enter individual values into each cell in a column of a tablegrid control? I don't believe that's possible.
Inside a tablegrid control, all values have to come from the underlying query. I recommend writing a query to do these calculations, and using that query as the basis for the form - that would solve both the problem of displaying the calculated result as well as improving the load speed of the form (since database logic in determining query results is almost always more efficient than a macro going row-by-row).
Alternately, you could have the calculated field be standalone, showing only the calculated result for the currently selected row of the tablegrid control. In this scenario, the "form loaded" event would only do the calculation for the first row, and the calculating macro would be triggered each time the row selection changed.

Sales order create VBA script: Passing material number and Variant config

I am new to Excel VBA scripting below are the issue I am facing :
1) Picking Material number from the excel cell and passing to the sales order created BAPI.
Data declaration
Dim Material As String
Material = ActiveSheet.Range("E14")
oItemsIn.Value(1, "MATERIAL") = Material
In This case the error message is there "Material 2094266 does not exist in sales area"
but if I pass material "000000000002094266" then it work fine
How I can change the format with leading Zero in the material number after picking value from the cell?
2) How I can pass material config (variant config) for the line item I am passing below values
Set CFGS_REF = oBapiCtrl.DimAs(boOrder, "CreateFromData", "OrderCfgsRef")
Set CFGS_VK = oBapiCtrl.DimAs(boOrder, "CreateFromData", "OrderCfgsInst")
Set CFGS_VALUE = oBapiCtrl.DimAs(boOrder, "CreateFromData", "OrderCfgsValue")
'OrderCfgsRefinst
CFGS_REF.Value("POSEX") = "000010"
CFGS_REF.Value("CONFIG_ID") = "000010"
CFGS_REF.Value("ROOT_ID") = "00000010"
' forOrderCfgsVk
CFGS_VK.Value("CONFIG_ID") = "000010"
CFGS_VK.Value("INST_ID") = "00000010"
CFGS_VK.Value("CLASS_TYPE") = "300"
'OrderCfgsValue
CFGS_VALUE.Value("CONFIG_ID") = "000010"
CFGS_VALUE.Value("INST_ID") = "00000010" ' Item
CFGS_VALUE.Value("CHARC") = "PRG_ORD_SOURCE"
CFGS_VALUE.Value("Value") = "Excel"
But it throws an error of data mismatch at CFGS_REF.Value("POSEX") = "000010"
To add the leading zeroes back to your material number:
oItemsIn.Value(1, "MATERIAL") = Format(Material, "000000000000000000")

PivotTableWizard - Name of Data Fields as Column Headers

I am creating a PivotTable from an Excel Sheet using VBA PivotTableWizard method.
I do define two row fields and two data fields with sum function. By default the name of the data fields appear in the Pivot Table as row description right from the row field names.
I wish to display the name of the data fields as column headers. In the Wizard the user would drag the "Sum sign - Values" field into the Column Labels box. How can this be done by code?
This is what I do have so far:
' Create the PivotTable object based on the data on the selected sheet
Set tm_volumes_pivot_table = ActiveSheet.PivotTableWizard
'Page fields
Set tm_volumes_pivot_field = tm_volumes_pivot_table.PivotFields("Article Type")
tm_volumes_pivot_field.Orientation = xlPageField
'Row fields
Set tm_volumes_pivot_field = tm_volumes_pivot_table.PivotFields("Main Area")
tm_volumes_pivot_field.Orientation = xlRowField
Set tm_volumes_pivot_field = tm_volumes_pivot_table.PivotFields("Subarea")
tm_volumes_pivot_field.Orientation = xlRowField
'Column fields
'Must be Names of Data Fields - how?
'Data fields
Set tm_volumes_pivot_field = tm_volumes_pivot_table.PivotFields("Initial Volume")
tm_volumes_pivot_field.Orientation = xlDataField
tm_volumes_pivot_field.Function = xlSum
tm_volumes_pivot_field.NumberFormat = "#"
Set tm_volumes_pivot_field = tm_volumes_pivot_table.PivotFields("Final Volume")
tm_volumes_pivot_field.Orientation = xlDataField
tm_volumes_pivot_field.Function = xlSum
tm_volumes_pivot_field.NumberFormat = "#"
Transfer OP's answer from question:
When a pivot table is going to have more than one data field, there is a virtual field named Values in the drop zones of the PivotTable Field List. In VBA, this equivalent virtual field is named "Data". - This will be used to arrange the Data in columns.
'Define Pivot Fields (Rows / Columns - Attention to "Data" / Page)
tm_volumes_pivot_table.AddFields Array("Main Area", "Subarea"), "Data", "Article Type"

DataSet/DataGridView setting selected columns to a variable .VB

Is it possible to set a selected Data Grid View column name to a variable.
Example of my code.
Dim cmevoids As DataTable = ds.Tables(0)
Dim test As String
test = "event_code"
Dim Query = From payments In cmevoids.AsEnumerable() _
Where payments.Field(Of String)("event_code") = "MB120117"
Where payments.Field(Of String)("event_transaction_status") = "PAID"
Order By payments.Field(Of String)("event_code") _
Select New With {.event_code = payments.Field(Of String)(test), _
.event_transaction_status = payments.Field(Of String)("event_transaction_status"), _
.event_transaction_detail_amount = payments.Field(Of String)("event_transaction_detail_amount")}
dgvQuery.DataSource = Query.ToList()
I want to take w/e column the user selects from a combo box from the first data grid view and display it in a 2nd data grid view for query's.
I can get it to search and display the table selected by the variable given as shown by the test variable. But i can't get it to change the column name in the query data grid view to the name of the variable. I can only get it to name it w/e i have hard coded in, in this case event_code, event_transaction_status and event_transaction_detail_amount.
Any way to do this without hard code but variable?
What about populating the gridview like you have been but then change it after it is bound?
Dim Result as string = "w/e column the user selects from a combo box"
Dim i as integer = 0 'your colum index
GridView1.Columns(i).HeaderText = Result