I would like to create UDF alternative of INDIRECT() - volatile

As indirect() is volatile and there is no other way than using indirect in my files, I need to create a UDF equivalent/alternative to indirect.
As far as I have been is :
INDIRECTVBA(ref_text As String, Optional active_A1 As Boolean) As String
If active_A1 = False Then
ref_text = "=" & ref_text
ref_text = Application.ConvertFormula(Formula:=ref_text, fromReferenceStyle:=xlR1C1, toReferenceStyle:=xlA1)
INDIRECTVBA = Range(ref_text)
Else
INDIRECTVBA = Range(ref_text)
End If
End Function
At this point, I'm able to manage :
A1 and R1C1 input with A1 format as default,
In the same sheet or not,
With and without the name of sheet.
I have been googleing for hours, to go there ...
My final need is to handle range such as :
A1:B2 as ref_text => INDIRECTVBA("A1:B2") should return a range as A1:B2
R1C1:R2C3 as ref_text
Thanks for time,

Related

How add only required fields from table to dynamic temp table? - PROGRESS 4GL

I am new to progress 4gl and below is the query used to add all fields from a table to dynamic temp table except few fields but I am not sure how to add only required fields to dynamic temp table. Please help to modify the query I shared.
/* p-ttdyn2.p - a join of 2 tables */
DEFINE VARIABLE tth4 AS HANDLE.
DEFINE VARIABLE btth4 AS HANDLE.
DEFINE VARIABLE qh4 AS HANDLE.
DEFINE VARIABLE bCust AS HANDLE.
DEFINE VARIABLE bOrder AS HANDLE.
DEFINE VARIABLE i AS INTEGER.
DEFINE VARIABLE fldh AS HANDLE EXTENT 15.
bCust = BUFFER customer:HANDLE.
bOrder = BUFFER order:HANDLE.
CREATE TEMP-TABLE tth4.
tth4:ADD-FIELDS-FROM(bCust,"address,address2,phone,city,comments").
tth4:ADD-FIELDS-FROM(bOrder,"cust-num,carrier,instructions,PO,terms").
tth4:TEMP-TABLE-PREPARE("CustOrdJoinTT").
btth4 = tth4:DEFAULT-BUFFER-HANDLE.
FOR EACH customer WHERE cust.cust-num < 6, EACH order OF customer:
btth4:BUFFER-CREATE.
btth4:BUFFER-COPY(bCust).
btth4:BUFFER-COPY(bOrder).
END.
/* Create Query */
CREATE QUERY qh4.
qh4:SET-BUFFERS(btth4).
qh4:QUERY-PREPARE("for each CustOrdJoinTT").
qh4:QUERY-OPEN.
REPEAT WITH FRAME zz DOWN:
qh4:GET-NEXT.
IF qh4:QUERY-OFF-END THEN LEAVE.
REPEAT i = 1 TO 15:
fldh[i] = btth4:BUFFER-FIELD(i).
DISPLAY fldh[i]:NAME FORMAT "x(15)"
fldh[i]:BUFFER-VALUE FORMAT "x(20)".
END.
END.
btth4:BUFFER-RELEASE.
DELETE OBJECT tth4.
DELETE OBJECT qh4.
ADD-FIELDS-FROM only supports excluding fields that are not needed. Instead you can use ADD-LIKE-FIELD multiple times:
CREATE TEMP-TABLE tth4.
tth4:ADD-LIKE-FIELD("address", "customer.address").
tth4:ADD-LIKE-FIELD("address2", "customer.address2").
tth4:ADD-LIKE-FIELD("phone", customer.phone").
...
tth4:ADD-LIKE-FIELD("cust-num", "Order.cust-num").
...
tth4:TEMP-TABLE-PREPARE("CustOrdJoinTT").
btth4 = tth4:DEFAULT-BUFFER-HANDLE.
Depending on your use case, you can also invert the required field list to an except field list:
var handle ht,hb.
var longchar lcjson.
function invertFields returns character (
i_hb as handle,
i_crequired as char
):
var char cexcept,cfield.
var int ic.
do ic = 1 to i_hb:num-fields:
cfield = i_hb:buffer-field( ic ):name.
if lookup( cfield, i_crequired ) = 0 then
cexcept = cexcept + ',' + cfield.
end.
return substring( cexcept, 2 ).
end function.
create temp-table ht.
ht:add-fields-from(
buffer customer:handle,
invertFields( buffer customer:handle, "CustNum,Name" )
).
ht:temp-table-prepare( 'tt' ).
hb = ht:default-buffer-handle.
hb:buffer-create().
assign
hb::CustNum = 1
hb::Name = 'test'
.
hb:write-json( 'longchar', lcjson, true ).
message string( lcjson ).
https://abldojo.services.progress.com/?shareId=624993253fb02369b25437c4

Unable to do conversion of datatype in U-sql

I am facing issue doing some transformations using U-sql one of the issue is while changing the Date format, Only when I skip the First rows(1) I am able to convert the date format. But I do need the column names so I cannot Skip the first row. Also I need to do some other transformations like data type conversion and simple concatenations.Below is my sample code.Kindly help.
DECLARE #dir string = "/storefolder/Sourcefile/dwfile3.csv";
DECLARE #file_set_path string = "/BCBSvermot/Sample_output.csv";
#data =
EXTRACT
CHECK_DATE string,
FROM #dir
USING Extractors.Csv(skipFirstNRows:1);
#result = SELECT
Convert.ToDateTime(CHECK_DATE).ToString("dd-MM-yyyy") AS CHECK_DATE
FROM #data;
OUTPUT #result
TO #file_set_path
USING Outputters.Csv();
Thanks,
Rav
You can declare a function similar to this:
DECLARE #func Func<string,string> =
(s) =>{
DateTime i;
var x = DateTime.TryParse(s, out i);
return x?((DateTime)i).ToString("dd-MM-yyyy",CultureInfo.CurrentCulture) : s;
};
Then you can use it on your queries
#result =
SELECT #func(CHECK_DATE) AS CHECK_DATE
FROM #data;

u-sql script can not obtain scalar value from dataset

In u-sql script I must extract a variable from file to a dataset and then use it to form a name of output file. How can I get the variable from the dataset?
In details.
I have 2 input files: csv file with a set of fields and a dictionary file. The 1st file has file name like ****ClintCode*****.csv. The 2nd file-dictionary has 2 fields with mapping: ClientCode - ClintCode2. My task is extract ClientCode value from the file name, get ClientCode2 from the dictionary, insert it as a field to output file (implemented), and, moreover, form the name of output file as ****ClientCode2****.csv.
Dictionary csv file has the content:
OldCode NewCode
6HAA Alfa
CCVV Beta
CVXX gamma
? Davis
The question is how to get ClientCode2 into scalar variable to write an expression for the output file?
DECLARE #inputFile string = "D:/DFS_SSC_Automation/Tasks/FundInfo/ESP_FAD_GL_6HAA_20170930.txt"; // '6HAA' is ClientCode here that mapped to other code in ClientCode_KVP.csv
DECLARE #outputFile string = "D:/DFS_SSC_Automation/Tasks/FundInfo/ClientCode_sftp_" + // 'ClientCode' should be replaced with ClientCode from mapping in ClientCode_KVP.csv
DateTime.Now.ToString("yyyymmdd") + "_" +
DateTime.Now.ToString("HHmmss") + ".csv";
DECLARE #dictionaryFile string = "D:/DFS_SSC_Automation/ClientCode_KVP.csv";
#dict =
EXTRACT [OldCode] string,
[NewCode] string
FROM #dictionaryFile
USING Extractors.Text(skipFirstNRows : 1, delimiter : ',');
#theCode =
SELECT Path.GetFileNameWithoutExtension(#inputFile).IndexOf([OldCode]) >= 0 ? 1 : 3 AS [CodeExists],
[NewCode]
FROM #dict
UNION
SELECT *
FROM(
VALUES
(
2,
""
)) AS t([CodeExists],[NewCode]);
#code =
SELECT [NewCode]
FROM #theCode
ORDER BY [CodeExists]
FETCH 1 ROWS;
#GLdata =
EXTRACT [ASAT] string,
[ASOF] string,
[BASIS_INDICATOR] string,
[CALENDAR_DATE] string,
[CR_EOP_AMOUNT] string,
[DR_EOP_AMOUNT] string,
[FUND_ID] string,
[GL_ACCT_TYPE_IND] string,
[TRANS_CLIENT_FUND_NUM] string
FROM #inputFile
USING Extractors.Text(delimiter : '|', skipFirstNRows : 1);
// Prepare output dataset
#FundInfoGL =
SELECT "" AS [AccountPeriodEnd],
"" AS [ClientCode],
[FUND_ID] AS [FundCode],
SUM(GL_ACCT_TYPE_IND == "A"? System.Convert.ToDecimal(DR_EOP_AMOUNT) : 0) AS [NetValueOtherAssets],
SUM(GL_ACCT_TYPE_IND == "L"? System.Convert.ToDecimal(CR_EOP_AMOUNT) : 0) AS [NetValueOtherLiabilities],
0.0000 AS [NetAssetsOfSeries]
FROM #GLdata
GROUP BY FUND_ID;
// NetAssetsOfSeries calculation
#FundInfoGLOut =
SELECT [AccountPeriodEnd],
[NewCode] AS [ClientCode],
[FundCode],
Convert.ToString([NetValueOtherAssets]) AS [NetValueOtherAssets],
Convert.ToString([NetValueOtherLiabilities]) AS [NetValueOtherLiabilities],
Convert.ToString([NetValueOtherAssets] - [NetValueOtherLiabilities]) AS [NetAssetsOfSeries]
FROM #FundInfoGL
CROSS JOIN #code;
// Output
OUTPUT #FundInfoGLOut
TO #outputFile
USING Outputters.Text(outputHeader : true, delimiter : '|', quoting : false);
As David points out: You cannot assign query results to scalar variables.
However, we have a dynamic partitioned output feature in private preview right now that will give you the ability to generate file names based on column values. Please contact me if you want to try it out.
You can't. Please see Convert Rowset variables to scalar value.
You may still be able to achieve your ultimate goal in a different manner. Please consider re-writing your post with clear & concise language, small dataset, expected output, and a very minimal amount of code needed to repro - remove all details and nuances that aren't necessary to create a test case.

Checking content of textbox vb.net

I am using a text box for input to my SQL query. Based on the input I create a certain query and display the data in a gridview.
However I wish to make an adjustment for my users.
They often make an input like PL26... However this is not a valid name in the database to search for. Therefore I want to CHECK their input, and alter it accordingly, so they don't have to think about it.
I happen to know that when they type PL26 the correct input would be PL000026 ... The entity to search for is always "PL" + 6 characters/numbers... so if they wrote PL155, the number/string I pass to the sql query should become PL + 000 + 155 = PL000155.
I hope someone can help me how to accomplish this. That is if it is possible?
My idea/Pseudo code would be something like
If tbInput.txt's FIRST 2 CHARS are PL, then check total length of string
if StringLength < 8 characters, then
if length = 2 then ADD 4 0' after PL...
if length = 3 then add 3 0's after PL...
if length = 3 then add 3 0's after PL..
etc
....
...
Here we go:
Private Sub Button21_Click(sender As System.Object, e As System.EventArgs) Handles Button21.Click
Debug.Print(formatCode("PL1"))
Debug.Print(formatCode("PL"))
Debug.Print(formatCode("PL01"))
Debug.Print(formatCode("PL155"))
End Sub
Private Function formatCode(userInput As String) As String
Dim returnVal As String
If userInput.Length < 8 Then
returnVal = String.Concat(userInput.Substring(0, 2), userInput.Substring(2, userInput.Length - 2).PadLeft(6, "0"))
Else
returnVal = userInput
End If
Return returnVal
End Function
You may need to add some validation ensuring it starts with PL etc.
The following will work as long as there are no other non-numeric characters in between the PL and the numbers. You can always add it in your validation.
Dim newInput As String
If (input.StartsWith("PL")) Then
input = input.Remove(0, 2)
End If
' If this fails then it means the input was not valid
Dim numberPart = Convert.ToInt32(input)
newInput = "PL" + numberPart.ToString("D6")
Exctract a number by removing prefix "PL"
Parse to Integer
Use Custom Numeric Format Strings(zero placeholder) for adding zeros and prefix
Const PREFIX As String = "PL"
Dim exctractedNumber As Int32
If Int32.TryParse(tbInput.txt.Replace(PREFIX, String.Empty), exctractedNumber) = False Then
'Error nahdling
Exit Sub
End If
Dim finalFormat As String = String.Format("'{0}'000000", PREFIX)
Dim finalValue As String = exctractedNumber.ToString(finalFormat)
I would make use of the handy PadLeft method:
Dim input As String = "PL26"
Dim number As String = input.Substring(2, input.Length - 2)
If number.Length <> 6 Then
number = number.PadLeft(6, "0"C)
End If
MSDN String.PadLeft

Conversion from string "x" to type 'Integer' is not valid

I get the following error when trying to create a default row in the asp.net dropdown: Conversion from string "x" to type 'Integer' is not valid.
CmbSalesAgents is the drop down control.
DefaultSalesAgent is the entity object (has values)
x is a concatenation of a numeric value and a string
**
Dim DefaultSalesAgent = (From o In db.PayoutRegisters
Join s In db.SalesAgents On s.SalesAgentId Equals o.SalesAgentID
Where o.PayoutRegisterID = PayoutRegisterID
Select o.PayoutRegisterID, x = s.CSRName + " (" + o.PaidThruDate.ToString + ")").ToList
If DefaultSalesAgent.Count > 0 Then
CmbSalesAgents.Items.Insert(0, New ListItem(DefaultSalesAgent.Item("x").ToString, PayoutRegisterID))
Else
CmbSalesAgents.Items.Insert(0, New ListItem("Select Sales Agent Payout Register", 0))
End If
Since DefaultSalesAgent is a list object then you should access its items through integer index not a string:
DefaultSalesAgent.Item(integer_index)
If you specifically need to insert the row based off a string value, you can replace
DefaultSalesAgent.Item("x")
With
DefaultSalesAgent.Item(DefaultSalesAgent.FindIndex(x => x.StartsWith("x")));
You can also use contains instead of startswith depending on your needs. Please note this is only if you specifically need to look for strings as it's a lot more expensive than accessing an index in the list.

Resources