Using custom table to feed drop-down list datasource - kentico

Let's assume that I have Custom Table named Possible URL target parameters with code name xyz.PossibleTargets with 2 columns:
Explanation and Value.
How to feed drop-down field on page type with data to have Value (from table) as Value and Explanation as name in drop-down?
What I already tried and it is not working:
Generate value;name pairs divided by newline and place it as List of options:
z = ""; foreach (x in CMSContext.Current.GlobalObjects.CustomTables["xyz.PossibleTargets"].Items) {z += x.GetValue("Value"); z +=";"; z += x.GetValue("Explanation"); z += "\n" }; return z;
Validator do no allow me to do such trick.
Set option Macro expression and provide enumerable object:
CMSContext.Current.GlobalObjects.CustomTables["xyz.PossibleTargets"].Items
In Item transformation: {%Explanation%} and in Value column {%TargetValue%}.
This do not work also.
Dropdown configuration
How to do this correctly? Documentation and hints on the fields are not helpful.
Kentico v11.0.26

I think that you should do it without marking field as a macro. Just type there the macro. Take a look on screen

No need to use a macro, use straight SQL, using a macro only complicates what appears to be a simple dropdown list.
SELECT '', '-- select one --' AS Explanation
UNION
SELECT TargetValue, Explanation
FROM xyz_PossibleTargets -- make sure to use the correct table name
ORDER BY ExplanationText
This should populate exactly what you're looking for without the complication of a macro.

Related

Cognos Static prompt values to be passed to SQL

I have a static prompt which is a single select. In that I have two values lets call it A and B. So when I select option 'A' my report pulls all data from the DB which is expected. So when user Select option 'B' the report should pull only the records whose code = 'M'. Here code is a column name in the report.
Note: For option 'A' I don't need to set any prompt in the report because it should pull all records by default.
Let's assume your parameter name is param and data item is named item.
Filter expression:
if (?param? = 'A')
then ([item])
else ('M')
= [item]
Note: You absolutely need to use a prompt. The result of selecting A should be to not filter.
I think I understand, try this:
Make the prompt a single value (i.e. B) with a use value of 'M'
Make the HEADER TEXT for the prompt A (so it is not an actual selection)
Make the filter optional
if the user selects A - the prompt is NULL and the optional filter is ignored
if the user selects B - the filter [Some data item] = ?YourParm? will occur
Also, if you prefer to not have header text
you can make static values A, B and modify the optional filter to be like this:
(?YourParm? <> 'M') OR ([Some data item] = ?YourParm?)

Replace all error values of all columns after importing datas (while keeping the rows)

An Excel table as data source may contain error values (#NA, #DIV/0), which could disturbe later some steps during the transformation process in Power Query.
Depending of the following steps, we may get no output but an error. So how to handle this cases?
I found two standard steps in Power Query to catch them:
Remove errors (UI: Home/Remove Rows/Remove Errors) -> all rows with an error will be removed
Replace error values (UI: Transform/Replace Errors) -> the columns have first to be selected for performing this operations.
The first possibility is not a solution for me, since I want to keep the rows and just replace the error values.
In my case, my data table will change over the time, means the column name may change (e.g. years), or new columns appear. So the second possibility is too static, since I do not want to change the script each time.
So I've tried to get a dynamic way to clean all columns, indepent from the column names (and number of columns). It replaces the errors by a null value.
let
Source = Excel.CurrentWorkbook(){[Name="Tabelle1"]}[Content],
//Remove errors of all columns of the data source. ColumnName doesn't play any role
Cols = Table.ColumnNames(Source),
ColumnListWithParameter = Table.FromColumns({Cols, List.Repeat({""}, List.Count(Cols))}, {"ColName" as text, "ErrorHandling" as text}),
ParameterList = Table.ToRows(ColumnListWithParameter ),
ReplaceErrorSource = Table.ReplaceErrorValues(Source, ParameterList)
in
ReplaceErrorSource
Here the different three queries messages, after I've added two new column (with errors) to the source:
If anybody has another solution to make this kind of data cleaning, please write your post here.
let
src = Excel.CurrentWorkbook(){[Name="Tabelle1"]}[Content],
cols = Table.ColumnNames(src),
replace = Table.ReplaceErrorValues(src, List.Transform(cols, each {_, "!"}))
in
replace
Just for novices like me in Power Query
"!" could be any string as substitute for error values. I initially thought it was a wild card.
List.Transform(cols, each {_, "!"}) generates the list of error handling by column for the main funcion:
Table.ReplaceErrorValues(table_with errors, {{col1,error_str1},{col2,error_str2},{},{}, ...,{coln,error_strn}})
Nice elegant solution, Sergei

Crystal Reports 11 Compare All Data in Group to Specific Value

I have a crystal report I need to modify to leave out duplicate rows by "name". So in Section Expert I am putting in a formula in Suppress and I cannot figure out how to compare the current name field being added to all the previous names that are in the group already. I was trying to use the Filter() function, but for the String array parameters I don't know what to enter that would be all of the other names previously added to the group. I need to compare the current name being added and see if it is already in the group so I can then compare another field called "date" and if the date of the field being added is more recent then the date of the duplicate name it will over write the row and only show the row with the most recent date.
Basically the question is how do I create an array with all the current fields already in the group(or does one exist already) so that I may use the Filter() function to see if the current name being added is already in that array of names added?
Well I figured it out, so for anyone who runs into this here is my solution.
first off I made a formula in the "formula fields" section that creates two arrays when reading the data from the database and keeps only one copy of each id and date in the record. Then for any other records that have the same id it will compare the date of that record to the record in the array with the same name and if the date is greater(later) then it will replace the date with the currently read in one. I named this formula field idArray.
Global StringVar Array idArray;
Global DateVar Array expArray;
BooleanVar addName;
NumberVar x;
StringVar idTest;
StringVar expDateTest;
whilereadingrecords;
(
addName := true;
for x := 1 to Ubound(idArray) step 1 do
(
if({hrpersnl.p_empno} = idArray[x]) then
(
addName := false;
if(Date({nemphist.enddate}) > expArray[x]) then
expArray[x] := Date({nemphist.enddate});
)
);
if(addName = true) then
(
reDim Preserve idArray[Ubound(idArray) + 1];
reDim Preserve expArray[Ubound(expArray) + 1];
idArray[Ubound(idArray)] := {hrpersnl.p_empno};
expArray[Ubound(expArray)] := Date({nemphist.enddate});
//idTest := idTest + ' ' + {hrpersnl.p_empno};
//expDateTest := expDateTest + ' ' + toText(Date({nemphist.enddate}));
);
//idTest
//Ubound(idArray)
//expDateTest
)
The commented out lines are what I used for testing to see how the arrays were building. I left them in there just as an example of how to debug crystal reports, since it doesn't come with a debugger.
The next step is to create a record suppression formula. In the Report menu I went to "section expert" and in the "Details" section of my group I clicked the little x-2 button next to the "Suppress (No Drill-Down)" option. I then inserted this code that looks at the current record's id and date and if the id is in the first array it will take its position and use that to retrieve the date from the second array and if the current record's date is less than the date we now know to be the max then it will suppress the record.
Global StringVar Array idArray;
Global DateVar Array expArray;
NumberVar x;
BooleanVar suppress := false;
for x := 1 to Ubound(idArray) do
(
if({hrpersnl.p_empno} = idArray[x]) then
if(Date({nemphist.enddate}) < expArray[x]) then
suppress := true;
);
if(suppress = true) then
true
else
false
Some lessons learned along the way...
Crystal Reports does global variables in a weird way. It took me a few hours of fudging around with them to figure out that you can basically use them anywhere in the report as long as you declare them in each section you put them in with the Global [vartype] "name" syntax. Even though you are re-declaring it each time Crystal does not remove the value of it or reset it or anything.
This operator ":=" is different than "=". The ":=" operator is used to set values for variables whereas the "=" seems to be used only for comparisons.
Crystal reports is really weird with its design. If you do want your formula field to return a specific variable or something you just type in that variable name without a ";" after it. Anything without a ";" after it is considered the end of the formula. So if you get this dumb "oh this code looks like its not part of the formula" error then it is because you didn't put a ";" after something and Crystal is assuming your function is ending at the location. But if you don't put a variable without a ";" after it your formula with just return "false" by default. So in my formula where I have //idTest
//Ubound(idArray)
//expDateTest
all I have to do is uncomment the variable I want to be returned and the formula will do so.

writing an excel formula with multiple options for a single parameter

I would like to access information from a HTTP based API and manipulate it with excel.
The API returns about 20 pieces of information, and you can get that information by looking up any number of about ten lookup fields: name, serial number etc.
I want to write a function similar to the Match Function in excel where one of the parameters (in this case MATCH TYPE) has multiple possible values.
I have a list of values (the 20 pieces of information the API can return) and I want to make these pieces of information the possible return values for one of the Functions parameters.
How do I do I create a function where one parameter has a list of possible values?
And how do I add tooltip help statements to those parameter options so people know what they are?
You want to use an Enum.
In the declarations part of your module (before any subs or functions) you can place code like this.
Enum MyFunctionsArgValue
LessThan
Equal
GreaterThan
End Enum
This will assign each of these keywords an integer value, starting at zero and counting up. So LessThan = 0, Equal = 1, and GreaterThan = 2. (You can actually start at any number you want, but the default is usually fine.)
Now you can use it in your function something like this.
Function MySuperCoolFunction(matchType as MyFunctionsArgValue)
Select Case matchType
Case LessThan
' do something
Case Equal
' do it different
Case GreaterThan
' do the opposite of LessThan
End Select
End Function
To get the tool tip, you need to use something called an Attribute. In order to add it to your code, you'll need to export the *.bas (or *.cls) file and open it in a regular text editor. Once you've added it, you'll need to import it back in. These properties are invisible from inside of the VBA IDE. Documentation is sketchy (read "nonexistent"), so I'm not sure this works for an Enum, but I know it works for functions and module scoped variables.
Function/Sub
Function MySuperCoolFunction(matchType as MyFunctionsArgValue)
Attribute MySuperCoolFunction.VB_Description = "tool tip text"
Module Scoped Var
Public someVar As String
Attribute someVar.VB_VarDescription = "tooltip text"
So, you could try this to see if it works.
Enum MyFunctionsArgValue
Attribute MyFunctionsArgValue.VB_VarDescription = "tool tip text"
LessThan
Equal
GreaterThan
End Enum
Resources
https://www.networkautomation.com/automate/urc/resources/help/definitions/Sbe6_000Attribute_DefinintionStatement.htm
http://www.cpearson.com/excel/CodeAttributes.aspx

JqGrid - losing ability to sort and perform multipleSearch when column header text is changed programmatically on gridComplete

This is my jqgrid - $("#list1")
When it loads, i.e. on the gridComplete event, I need to rename the column header texts.
Original column header texts are in this format - Colomn1, Column2 ...
On gridComplete, I change these header texts like this:
$("#list1_Column" + someNumber).text(someText);
However on doing this, I lose the ability to sort columns. Column headers are no longer clickable and hence I cannot sort the grid after this custom programmatic editing.
Similar thing happens when I try changing the texts in the search dropdown list (search modal - using multipleSearch: true)
When, on gridComplete, I change text values in the select list as per the grid column headers, like this -
var select = $('#grid_wrapper #fbox_list1 .ui-widget-content .sf .fields select');
$('#grid_wrapper #fbox_list1 .ui-widget-content .sf .fields select option').remove();
$.each(data, function (i, item) {
select.append('<option value="Column' + item.id + '">' + item.ColumnName + '</option>')
});
...I lose the ability to perform multiple search, i.e. the + and - buttons in the search modal disappear.
How do I get around these two issues? Retaining ability to sort and perform multiple search after having changed column header and search list text values on load.
Please guide.
The column header <th> element has two child elements: one <span> with the text of the column header and another with the sort icons which are hidden the most time. So if you want to change the text manually you should use another selector
$("#list1_Column" + someNumber+ " > span").text(someText);
If you do so you will change the text on the page, but not change the text in the colNames or in the colModel (if you use label property instead of colNames). The text will be used for example to create Multisearch dialog. You can make changes in the colModel with respect of setColProp method or use getGridParam to get reference to any internal parameter of jqGrid (which are objects like inclusive colNames and colModel) and then make any changes which you need.
The best way in my opinion to solve the described problems is to use setLabel method to change the text in the column header:
$("#list1").jqGrid('setLabel','ColumnName','My new Name');
this will solve both problems.

Resources