How can I SELECT records using a select list made of foreign keys? - universe

I have a table, DEBTOR, with a structure like this:
and a second table, DEBTOR.INFO structured like this:
I have a select list made of record IDs from the DEBTOR.INFO table. How can I
select * from DEBTOR WHERE 53 IN (name of select list)?
Is this even possible?
I realize this query looks more like SQL than RetrieVe but I wrote it that way for an easier understanding of what I'm trying to accomplish.
Currently, I accomplish this query by writing
SELECT DEBTOR WITH 53 EQ [paste list of DEBTOR.INFO record IDs]
but obviously this is unwieldy for large lists.

It looks to me that you cant do that. Even if you use and i-descriptor, It only works in one direction. TRANS("DEBTOR.INFO",53,0,"X") works from the DEBTOR file but not the other way. So TRANS("DEBTOR",#ID,53,"X") from DEBTOR.INFO will return nothing.
See this article on U2's site for a possible solution.

Would something like this work (two steps):
SELECT DEBTOR.INFO SAVING PACKET
LIST DEBTOR ....
This creates a select list of the data in the PACKET field in the DEBTOR.INFO file and makes it active. (If you have duplicate values that way you can add the keyword UNIQUE after SAVING).
Then the subsequent LIST command uses that active select list which contains values found in the #ID field of the file DEBTOR.

Not sure if you are still looking at this, but there is a simple option that will not require a lot of programming.
I did it with a program, a subroutine and a dictionary item.
First I set a named common variable to contain the list of DEBTOR.INFO ids:
SETLIST
*
* Use named common to hold list of keys
COMMON /MYKEYS/ KEYLIST
*
* Note for this example I am reading the list from SAVEDLISTS
OPEN "SAVEDLISTS" TO FILE ELSE STOP "CAN NOT OPEN SAVEDLISTS"
READ KEYLIST FROM FILE, "MIKE000" ELSE STOP "NO MIKE000 ITEM"
Now, I can create a subroutine that checks for a value in that list
CHECKLIST
SUBROUTINE CHECKLIST( RVAL, IVAL)
COMMON /MYKEYS/ KEYLIST
LOCATE IVAL IN KEYLIST <1> SETTING POS THEN
RVAL = 1
END ELSE RVAL = 0
RETURN
Lastly, I use a dictionary item to call the subroutine with the field I am looking for:
INLIST:
I
SUBR("CHECKLIST", FK)
IN LIST
10R
S
Now all I have to do is put the correct criteria on my list statement:
LIST DEBTOR WITH INLIST = 1 ACCOUNT STATUS FK

Id use the very powerfull EVAL with an XLATE ;
SELECT DEBTOR WITH EVAL \XLATE('DEBTOR.INFO',#RECORD<53>,'-1','X')\ NE ""

Related

"Operation must use an updateable query" in MS Access when the Updated Table is the same as the source

The challenge is to update a table by scanning that same table for information. In this case, I want to find how many entries I received in an Upload dataset that have the same key (effectively duplicate instructions).
I tried the obvious code:
UPDATE Base AS TAR
INNER JOIN (select cdKey, count(*) as ct FROM Base GROUP BY cdKey) AS CHK
ON TAR.cdKey = CHK.cdKey
SET ctReferences = CHK.ct
This resulted in a non-updateable complaint. Some workarounds talked about adding DISTINCTROW, but that made no difference.
I tried creating a view (query in Ms/Access parlance); same failure.
Then I projected the set (SELECT cdKey, count(*) INTO TEMP FROM Base GROUP BY cdKey), and substituted TEMP for the INNER JOIN which worked.
Conclusion: reflexive updates are also non-updateable.
An initial thought was to embed a sub-select in the update, for example:
UPDATE Base TAR SET TAR.ctReferences = (select count(*) from Base CHK where CHK.cd = TAR.cd)
This also failed.
As this is part of a job I am calling, this SQL (like the other statements) are all strings executed by CurrentDb.Execute statements. I thought maybe I could make this a DLookup, I found that as cd is a string, I had a gaggle of double- and triple-quoted elements that was too messy to read (and maintain).
Best solution was to write a function so I could avoid having to do any sort of string manipulation. Hence, in a module there's a function:
Public Function PassHelperCtOccurs(ByRef cdX As String) As Long
PassHelperCtOccurs = DLookup("count(*)", "Base", "cd='" & cdX & "'")
End Function
And the call is:
CurrentDb().Execute ("UPDATE Base SET ctOccursCd =PassHelperCtOccurs(cd)")

Converting JSON into Table (PowerQuery)

What would be a correct PowerQuery syntax to extract the information from this Web JSON into a table:
I'm not very familiar with PowerQuery, and this is probably the only time I'll need this, so I'd be grateful if someone would help me out without refering me to documentation. Thanks
[{"time_entry_group": {"minutes": 301,"time_entries_params": {"locked": "0","from": "2021-02-01","to": "2021-02-28","customer_id": "11223344","project_id": "223388","service_id": "435248"},"revenue": 57691.6666666667,"project_id": 223388,"project_name": "Scrb","service_id": 435248,"service_name": "Meetings","month": "202102"}}
, {"time_entry_group": {"minutes": 1175,"time_entries_params": {"locked": "1","from": "2021-01-01","to": "2021-01-31","customer_id": "11223344","project_id": "223388","service_id": "421393"},"revenue": 225208.333333333,"project_id": 223388,"project_name": "Scrb","service_id": 421393,"service_name": "Design","month": "202101"}}
, {"time_entry_group": {"minutes": 24,"time_entries_params": {"locked": "1","from": "2021-01-01","to": "2021-01-31","customer_id": "11223344","project_id": "3168911","service_id": "95033"},"revenue": 4600.0,"project_id": 3168911,"project_name": "youkn Dev","service_id": 95033,"service_name": "Reviews","month": "202101"}}]
For future reference, if you have a column that you need to expand, you can instead click this arrow icon to the right of the column name. Clicking it should display a menu that should then allow you to specify which nested columns you want to get expand or get at. To be clear, it will expand that column for all rows in that table, not just one.
The JSON you've included is basically an array of objects, so maybe use:
Json.Document to parse the JSON, which should give you a list of records
Table.FromRecords to turn the list of records into a table.
Table.ExpandRecordColumn to expand a nested record columns.
Example implementation:
let
json = "[{""time_entry_group"":{""minutes"":301,""time_entries_params"":{""locked"":""0"",""from"":""2021-02-01"",""to"":""2021-02-28"",""customer_id"":""11223344"",""project_id"":""223388"",""service_id"":""435248""},""revenue"":57691.6666666667,""project_id"":223388,""project_name"":""Scrb"",""service_id"":435248,""service_name"":""Meetings"",""month"":""202102""}},{""time_entry_group"":{""minutes"":1175,""time_entries_params"":{""locked"":""1"",""from"":""2021-01-01"",""to"":""2021-01-31"",""customer_id"":""11223344"",""project_id"":""223388"",""service_id"":""421393""},""revenue"":225208.333333333,""project_id"":223388,""project_name"":""Scrb"",""service_id"":421393,""service_name"":""Design"",""month"":""202101""}},{""time_entry_group"":{""minutes"":24,""time_entries_params"":{""locked"":""1"",""from"":""2021-01-01"",""to"":""2021-01-31"",""customer_id"":""11223344"",""project_id"":""3168911"",""service_id"":""95033""},""revenue"":4600,""project_id"":3168911,""project_name"":""youkn Dev"",""service_id"":95033,""service_name"":""Reviews"",""month"":""202101""}}]",
parsed = Json.Document(json),
initialTable = Table.FromRecords(List.Transform(parsed, each [time_entry_group])),
expanded = Table.ExpandRecordColumn(initialTable, "time_entries_params", {"locked", "from", "to", "customer_id"})
in
expanded
One thing about the code above is that it doesn't expand nested fields project_id and service_id (present within time_entries_params). This is because these columns already exist in the table (and having duplicate column names would cause an error). I've assumed this isn't a problem, as the nested values aren't different.

How to create a key value map when there are duplicate keys?

I am new to pig. I have the below output.
(001,Kumar,Jayasuriya,1123456754,Matara)
(001,Kumar,Sangakkara,112722892,Kandy)
(001,Rajiv,Reddy,9848022337,Hyderabad)
(002,siddarth,Battacharya,9848022338,Kolkata)
(003,Rajesh,Khanna,9848022339,Delhi)
(004,Preethi,Agarwal,9848022330,Pune)
(005,Trupthi,Mohanthy,9848022336,Bhuwaneshwar)
(006,Archana,Mishra,9848022335,Chennai)
(007,Kumar,Dharmasena,758922419,Colombo)
(008,Mahela,Jayawerdana,765557103,Colombo)
How can I create a map of the above so that the output will look something like,
001#{(Kumar,Jayasuriya,1123456754,Matara),(Kumar,Sangakkara,112722892,Kandy),(001,Rajiv,Reddy,9848022337,Hyderabad)}
002#{(siddarth,Battacharya,9848022338,Kolkata)}
I tried the ToMap function.
mapped_students = FOREACH students GENERATE TOMAP($0,$1..);
But I am unable dump the output from the above command as the process throws an error and stops there. Any help would be much appreciated.
I think you are trying to achieve is group records into tuples having same id.
according to TOMAP function it Converts key/value expression pairs into a map, hence you wont be able to group your rest records, and will result in something like unable to open iterator for alias..
as per your desiring output here is the piece of code.
A = LOAD 'path_to_data/data.txt' USING PigStorage(',') AS (id:chararray,first:chararray,last:chararray,phone:chararray,city:chararray);
If you do not want to give schema then:
A = LOAD 'path_to_data/data.txt' USING PigStorage(',');
B = GROUP A BY $0; (this relation will group all your records based on your first column)
DESCRIBE B; (this will show your described schema)
DUMP B;
Hope this helps..

Returning multiple record IDs with an I-Descriptor

Is it possible to create an I-descriptor that returns multiple record keys when the only the first part of the key is known? For example I have Quote Header record in the QTH file and need to reference all of the Quote Detail records in the QTD file.
A QTH record has an ID of '1159' so I know that all of the related QTD records will begin with '1159*'.
Entering LIST QTD LIKE "1159*]" returns
1159*D080*L*096*20
1159*D060*D*Shipping*
1159*D060*L*063*10
1159*D060*D*Dakota Sign*
1159*D080*L*092*30
I have tried a number of variations of the TRANS() statement in an I-Descriptor to return a multivalued list, all to no avail. Can this be done and if so how?
If I understand you want an I-type in QTH to tell you the IDS in QTD that start with 1159.
You should be able to do this with a subroutine call.
The I-Type would be
1: I
2: SUBR("GETQTDIDS)
3:
4: QTD-IDS
5: 10L
6: M
The subroutine would be:
SUBR GETQTDIDS(IDLIST)
EXECUTE "SELECT QTD WITH #ID LIKE ":(#ID):"..." CAPTURING IDLIST
RETURN
END
I would try something like that. Of course if you had an I-type in QTD which pulled out the first part of the #ID and indexed it you could use GETINDEX instead.
And of course if you had that its much easier to create an I-type in QTD which pulled information from QTH.

VBA Validation List Error

I am pretty new to programming in vba. I need some coding help which I am not able to find the solution after I tried Googling for the solution.
Currently I have a self-defined type called category mapping. The type will be used to contain the items which I want to put as the option for the vadliation list. It looked as below:
Public Type categoryMapping
messageKey As Long
description As String
End Type
An example of the categoryMapping is to store gender codes, 6000 stands for Male, 6001 stands for Female.
Display of the Validation List
As I have all stored them in an array, displaying them is not easy. What I have done is as below:
'Validation drop down list for the whole row
If Has_Elements(mapping) Then
Dim code As String
Dim options() As categoryMapping
code = ""
options = mapping
Dim j As Integer
For j = LBound(options) To UBound(options)
code = code & options(j).messageKey & ": " & options(j).description & ","
Next j
With Range(Rows(7).Address).Validation 'TODO: Need to refactor
.Add Type:=xlValidateList, _
AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, _
Formula1:=code
.InCellDropdown = True
.InputMessage = "Please choose from of the following"
.ShowInput = True
End With
End If
Is there a easier to display them since I have already put all the item to be displayed into a array? Is it possible that I can call the array directly?
Use Cells
From the code above, it can be seen that I have use the address of the whole row to contain validation list, because actually what I want is the whole row, except the header cells to contain the validation list.
With Cells(7,1).Validation 'TODO: Need to refactor
.Add Type:=xlValidateList, _
AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, _
Formula1:=code
.InCellDropdown = True
.InputMessage = "Please choose from of the following"
.ShowInput = True
End With
I tried using the code above to do, but it fails. Is there any way to go about doing it?
Combine multiple validation delete
Due to the problem mentioned above, I need to put in the code to delete the validation list for some column, as shown below:
'Delete the unneccessary validation
'TODO: refactor the code so that write in 1 line
Range(Columns(1).Address).Validation.Delete
Range(Columns(2).Address).Validation.Delete
Range(Columns(3).Address).Validation.Delete
Range(Columns(4).Address).Validation.Delete
Is there some ways that I can combine all the delete validation into a single statement?
Display part of the option
As you can see from above, when my users select a option from the validation list, the whole string appear.
For example, if I have "6000: Male" & "6001: Female" as the option, and I choose Male, I wished for "6000" to appear instead of "6000: Male". Is there a way to do it?
Validation data not exist after reopen
After I generate the validation list, I close the program and reopen it, there is a error that say "Excel found unreadable content in 'File name.xls'. Do you want to recover the contents of this workbook? If you trust the source of this workbook, click Yes.
When I click Yes, my excel open but all my validation list is gone! And I got the below as a error message.
-
error064240_01.xml
Errors were detected in file 'file_name'
-
Removed Feature: Data validation from /xl/worksheets/sheet2.xml.part
I was guessing that the error occur because the option in the validation list is not stored in the worksheet, but it is stored in the program memory, hence when I closed the program, the memory is loss.
If my guess is correct, is there any way to go around solving this problem? I was thinking of creating another worksheet that contain all the data in the validation list and let my cell validation list refer to them, but is there better ways to store them in the same worksheet?
The unreadable content is because you are storing the validation list in an array in memory. As soon as you close the worksheet, that array goes out of scope and ceases to exist. Rather than storing it in an array, write the list to a worksheet somewhere, I normally create a new sheet called lists.
The actual validation for your cell won't use VBA. Just create a dynamic named range (using offset() and counta() to populate your validation list from the relevant column in the lists sheet. Then use your VBA code to write the array above to that column. (http://chandoo.org/wp/2010/09/13/dynamic-data-validation-excel/)
As far as displaying different text in the validation and the dropdown, that sounds like more trouble than it is worth. Is it possible to just resize your cell so it only shows the first 4 digits?