I have successfully created the ERD with standard notations as per the UML with reference to ERD Sample
But I want to make lines exactly touching the field names as specified in this question ERD Or UML
is there and inbuilt facility available in plantuml or should I simply alter the x y position of the svg element using CSS ?
In theory it can be done using arrows from/to class members. However, it doesn't work as you'd expect:
#startuml
' hide the spot
hide circle
' avoid problems with angled crows feet
skinparam linetype ortho
entity "Entity01" as e01 {
* e1_id : number <<generated>>
__
* name : text
description : text
}
entity "Entity02" as e02 {
* e2_id : number <<generated>>
__
* e1_id : number <<FK>>
other_details : text
}
entity "Entity03" as e03 {
* e3_id : number <<generated>>
__
e1_id : number <<FK>>
other_details : text
}
e01 ||.left.o{ e02::e1_id
e01 |o.right.o{ e03::e1_id
#enduml
I'd call it a bug in PlantUML, because the lines end in the center of the entity rather than its edge. You could possibly get it fixed by reporting it. However, I doubt you can get a result as nice as the diagram in your question.
Playing around with up/down and left to right direction gets me a better result:
#startuml
' hide the spot
hide circle
' avoid problems with angled crows feet
skinparam linetype ortho
left to right direction
entity "Entity01" as e01 {
* e1_id : number <<generated>>
__
* name : text
description : text
}
entity "Entity02" as e02 {
* e2_id : number <<generated>>
__
* e1_id : number <<FK>>
other_details : text
}
entity "Entity03" as e03 {
* e3_id : number <<generated>>
__
e1_id : number <<FK>>
other_details : text
}
e01::e1_id ||.up.o{ e02::e1_id
e01::e1_id |o.down.o{ e03::e1_id
#enduml
But, again, I doubt this will work with your example. You can try!
Edit: Looking at this example, you can see that it's pretty close to the example you stated. I think the key is left to right direction.
Here is the DDL and table structure of the XML that I am working on. I'm able to parse a lot of the basic XML now but now I have a tag that repeats several times with this same name and then with the same child tags. I would like to get a separate column for each combination of parent and child tags and somehow have different names for each one of those. Here is the tag that repeats several times along with the four child tags.
<ProgSrvcAccomActyOtherGrp>
<ExpenseAmt>338351</ExpenseAmt>
<GrantAmt>0</GrantAmt>
<RevenueAmt>0</RevenueAmt>
<Desc>Equipment</Desc>
</ProgSrvcAccomActyOtherGrp>
Again, thank you!
-- DDL and sample data population, start
DECLARE #tbl TABLE (ID INT IDENTITY PRIMARY KEY, XMLData XML);
INSERT INTO #tbl (XMLData) VALUES
('<?xml version="1.0" encoding="utf-8"?>
<Return returnVersion="2019v5.0" xmlns="http://www.irs.gov/efile" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ReturnHeader binaryAttachmentCnt="0">
<ReturnTs>2021-02-11T21:27:00-07:00</ReturnTs>
<TaxPeriodEndDt>2020-06-30</TaxPeriodEndDt>
<ReturnTypeCd>990</ReturnTypeCd>
<TaxPeriodBeginDt>2019-07-01</TaxPeriodBeginDt>
<Filer>
<EIN>936022772</EIN>
<BusinessName>
<BusinessNameLine1Txt>OREGON STATE UNIVERSITY FOUNDATION</BusinessNameLine1Txt>
</BusinessName>
<BusinessNameControlTxt>OREG</BusinessNameControlTxt>
<PhoneNum>5417374218</PhoneNum>
<USAddress>
<AddressLine1Txt>4238 SW Research Way</AddressLine1Txt>
<CityNm>Corvallis</CityNm>
<StateAbbreviationCd>OR</StateAbbreviationCd>
<ZIPCd>973331068</ZIPCd>
</USAddress>
</Filer>
<BusinessOfficerGrp>
<PersonNm>Steven Schauble</PersonNm>
<PersonTitleTxt>Vice President & CFO</PersonTitleTxt>
<PhoneNum>5417377499</PhoneNum>
<SignatureDt>2021-02-12</SignatureDt>
</BusinessOfficerGrp>
<FilingSecurityInformation>
<IPAddress>
<IPv4AddressTxt>73.25.170.86</IPv4AddressTxt>
</IPAddress>
</FilingSecurityInformation>
<TaxYr>2019</TaxYr>
<BuildTS>2021-01-29 14:40:06Z</BuildTS>
</ReturnHeader>
<ReturnData documentCnt="11">
<IRS990 documentId="R000001" referenceDocumentId="R000010" softwareId="19009572" softwareVersionNum="v1.00">
<PrincipalOfficerNm>Shawn Scoville</PrincipalOfficerNm>
<USAddress>
<AddressLine1Txt>4238 SW Research Way</AddressLine1Txt>
<CityNm>Corvallis</CityNm>
<StateAbbreviationCd>OR</StateAbbreviationCd>
<ZIPCd>973331068</ZIPCd>
</USAddress>
<GrossReceiptsAmt>336252171</GrossReceiptsAmt>
<GroupReturnForAffiliatesInd>0</GroupReturnForAffiliatesInd>
<Organization501c3Ind>X</Organization501c3Ind>
<WebsiteAddressTxt>www.osufoundation.org</WebsiteAddressTxt>
<TypeOfOrganizationCorpInd>X</TypeOfOrganizationCorpInd>
<FormationYr>1947</FormationYr>
<LegalDomicileStateCd>OR</LegalDomicileStateCd>
<ActivityOrMissionDesc>The OSU Foundation partners with Oregon State University to engage our community, inspire investment, and steward resources to enhance the university''s excellence and impact.</ActivityOrMissionDesc>
<VotingMembersGoverningBodyCnt>39</VotingMembersGoverningBodyCnt>
<VotingMembersIndependentCnt>36</VotingMembersIndependentCnt>
<TotalEmployeeCnt>183</TotalEmployeeCnt>
<TotalVolunteersCnt>39</TotalVolunteersCnt>
<TotalGrossUBIAmt>0</TotalGrossUBIAmt>
<NetUnrelatedBusTxblIncmAmt>-568422</NetUnrelatedBusTxblIncmAmt>
<PYContributionsGrantsAmt>74724577</PYContributionsGrantsAmt>
<CYContributionsGrantsAmt>93028322</CYContributionsGrantsAmt>
<PYProgramServiceRevenueAmt>510476</PYProgramServiceRevenueAmt>
<CYProgramServiceRevenueAmt>1338931</CYProgramServiceRevenueAmt>
<PYInvestmentIncomeAmt>31179603</PYInvestmentIncomeAmt>
<CYInvestmentIncomeAmt>20095789</CYInvestmentIncomeAmt>
<PYOtherRevenueAmt>21307467</PYOtherRevenueAmt>
<CYOtherRevenueAmt>17916447</CYOtherRevenueAmt>
<PYTotalRevenueAmt>127722123</PYTotalRevenueAmt>
<CYTotalRevenueAmt>132379489</CYTotalRevenueAmt>
<PYGrantsAndSimilarPaidAmt>0</PYGrantsAndSimilarPaidAmt>
<CYGrantsAndSimilarPaidAmt>0</CYGrantsAndSimilarPaidAmt>
<PYBenefitsPaidToMembersAmt>0</PYBenefitsPaidToMembersAmt>
<CYBenefitsPaidToMembersAmt>0</CYBenefitsPaidToMembersAmt>
<PYSalariesCompEmpBnftPaidAmt>31629477</PYSalariesCompEmpBnftPaidAmt>
<CYSalariesCompEmpBnftPaidAmt>31621515</CYSalariesCompEmpBnftPaidAmt>
<PYTotalProfFndrsngExpnsAmt>0</PYTotalProfFndrsngExpnsAmt>
<CYTotalProfFndrsngExpnsAmt>0</CYTotalProfFndrsngExpnsAmt>
<CYTotalFundraisingExpenseAmt>17996976</CYTotalFundraisingExpenseAmt>
<PYOtherExpensesAmt>81790834</PYOtherExpensesAmt>
<CYOtherExpensesAmt>92045058</CYOtherExpensesAmt>
<PYTotalExpensesAmt>113420311</PYTotalExpensesAmt>
<CYTotalExpensesAmt>123666573</CYTotalExpensesAmt>
<PYRevenuesLessExpensesAmt>14301812</PYRevenuesLessExpensesAmt>
<CYRevenuesLessExpensesAmt>8712916</CYRevenuesLessExpensesAmt>
<TotalAssetsBOYAmt>816417531</TotalAssetsBOYAmt>
<TotalAssetsEOYAmt>833330950</TotalAssetsEOYAmt>
<TotalLiabilitiesBOYAmt>89894344</TotalLiabilitiesBOYAmt>
<TotalLiabilitiesEOYAmt>94381459</TotalLiabilitiesEOYAmt>
<NetAssetsOrFundBalancesBOYAmt>726523187</NetAssetsOrFundBalancesBOYAmt>
<NetAssetsOrFundBalancesEOYAmt>738949491</NetAssetsOrFundBalancesEOYAmt>
<InfoInScheduleOPartIIIInd>X</InfoInScheduleOPartIIIInd>
<MissionDesc>MISSION: The OSU Foundation partners with Oregon State University to engage our community, inspire investment, and steward resources to enhance the university''s excellence and impact. VISION: To create a better world by inspiring support of - and for - Oregon State University.</MissionDesc>
<SignificantNewProgramSrvcInd>0</SignificantNewProgramSrvcInd>
<SignificantChangeInd>0</SignificantChangeInd>
<ExpenseAmt>12674058</ExpenseAmt>
<GrantAmt>0</GrantAmt>
<RevenueAmt>0</RevenueAmt>
<Desc>SCHOLARSHIPS & OTHER STUDENT SUPPORT: The OSU Foundation distributed these amounts, in accordance with donor intent, to the University in FY20 to support students through scholarships, fellowships, and other awards. Through the years, donors have created over 1,975 unique scholarship and fellowship funds of various types and amounts at the OSU Foundation. These funds help ensure that an OSU education is accessible to qualified students, regardless of economic circumstances, and allow the University to recruit and retain the best and brightest students from Oregon and beyond.</Desc>
<ProgSrvcAccomActy2Grp>
<ExpenseAmt>39071677</ExpenseAmt>
<GrantAmt>0</GrantAmt>
<RevenueAmt>0</RevenueAmt>
<Desc>CAPITAL PROGRAMS: The OSU Foundation distributed these amounts, in accordance with donor intent, to the University, in FY20, to support the construction or renovation of campus facilities. Major projects in FY20 included: the Marine Studies Building in Newport, the Oregon Forest Science Complex, the Arts & Education Complex, renovations to: Merryfield Hall, President''s residence, Valley Football Center, P Wayne Valley Sports Performance Center, Reser Stadium, Gill Colosseum, and the softball complex.</Desc>
</ProgSrvcAccomActy2Grp>
<ProgSrvcAccomActy3Grp>
<ExpenseAmt>17167254</ExpenseAmt>
<GrantAmt>0</GrantAmt>
<RevenueAmt>0</RevenueAmt>
<Desc>INSTRUCTION AND RESEARCH: The OSU Foundation distributed these amounts, in accordance with donor intent, to the University, in FY20, to support teaching and research. With 150 endowed faculty positions at the University, donors to the OSU Foundation provide critically needed private funds to help recruit and retain world-class talent in the classrooms and labs. During the year, Foundation funds helped support OSU''s internationally recognized programs in marine sciences, forestry, and agricultural sciences, among others.</Desc>
</ProgSrvcAccomActy3Grp>
<ProgSrvcAccomActyOtherGrp>
<ExpenseAmt>4888</ExpenseAmt>
<GrantAmt>0</GrantAmt>
<RevenueAmt>0</RevenueAmt>
<Desc>Accounting services</Desc>
</ProgSrvcAccomActyOtherGrp>
<ProgSrvcAccomActyOtherGrp>
<ExpenseAmt>31223</ExpenseAmt>
<GrantAmt>0</GrantAmt>
<RevenueAmt>0</RevenueAmt>
<Desc>Advertising/Promotion</Desc>
</ProgSrvcAccomActyOtherGrp>
<ProgSrvcAccomActyOtherGrp>
<ExpenseAmt>290774</ExpenseAmt>
<GrantAmt>0</GrantAmt>
<RevenueAmt>0</RevenueAmt>
<Desc>Books, Periodicals & Subscriptions</Desc>
</ProgSrvcAccomActyOtherGrp>
<ProgSrvcAccomActyOtherGrp>
<ExpenseAmt>750</ExpenseAmt>
<GrantAmt>0</GrantAmt>
<RevenueAmt>0</RevenueAmt>
<Desc>Capital Outlay</Desc>
</ProgSrvcAccomActyOtherGrp>
<ProgSrvcAccomActyOtherGrp>
<ExpenseAmt>123611</ExpenseAmt>
<GrantAmt>0</GrantAmt>
<RevenueAmt>472080</RevenueAmt>
<Desc>Conferences, Meetings and Seminars</Desc>
</ProgSrvcAccomActyOtherGrp>
<ProgSrvcAccomActyOtherGrp>
<ExpenseAmt>541970</ExpenseAmt>
<GrantAmt>0</GrantAmt>
<RevenueAmt>0</RevenueAmt>
<Desc>Donor Cultivation/Stewardship</Desc>
</ProgSrvcAccomActyOtherGrp>
<ProgSrvcAccomActyOtherGrp>
<ExpenseAmt>19971</ExpenseAmt>
<GrantAmt>0</GrantAmt>
<RevenueAmt>87480</RevenueAmt>
<Desc>Dues and Memberships</Desc>
</ProgSrvcAccomActyOtherGrp>
<ProgSrvcAccomActyOtherGrp>
<ExpenseAmt>338351</ExpenseAmt>
<GrantAmt>0</GrantAmt>
<RevenueAmt>0</RevenueAmt>
<Desc>Equipment</Desc>
</ProgSrvcAccomActyOtherGrp>
<ProgSrvcAccomActyOtherGrp>
<ExpenseAmt>158235</ExpenseAmt>
<GrantAmt>0</GrantAmt>
<RevenueAmt>0</RevenueAmt>
<Desc>Information Technology</Desc>
</ProgSrvcAccomActyOtherGrp>
<ProgSrvcAccomActyOtherGrp>
<ExpenseAmt>594951</ExpenseAmt>
<GrantAmt>0</GrantAmt>
<RevenueAmt>0</RevenueAmt>
<Desc>Insurance</Desc>
</ProgSrvcAccomActyOtherGrp>
</IRS990>
</ReturnData>
</Return>');
WITH XMLNAMESPACES (DEFAULT 'http://www.irs.gov/efile')
SELECT ID
, ProgSrvcAccomActyOtherGrp = c.value('(ProgSrvcAccomActyOtherGrp/text())[1]', 'BIGINT')
FROM #tbl
CROSS APPLY XMLData.nodes('/Return/ReturnData/IRS990') AS t(c);
Omitting your XML blob, take a look at this:
WITH XMLNAMESPACES (DEFAULT 'http://www.irs.gov/efile')
SELECT c.query('.')
FROM #tbl
CROSS APPLY XMLData.nodes('/Return/ReturnData/IRS990/ProgSrvcAccomActyOtherGrp') AS t(c);
That gets all of the ProgSrvcAccomActyOtherGrp nodes out of the XML. If I'm understanding what you're describing as the next step, SQL isn't really set up for that. That is, it sounds like you're describing a result set with an unknown number of columns (i.e. you want N columns per ProgSrvcAccomActyOtherGrp node, but the number of nodes is unknown a priori). Search for "dynamic pivot" and buckle up.
Changing the number of the element worked! Thank you always learning!
CREATE VIEW VanHalen6AAA
AS
WITH XMLNAMESPACES (DEFAULT 'http://www.irs.gov/efile')
SELECT ID, FilingYear, FilingPeriod, FilingType, [FileName]
, ProgSrvcAccomActy3GrpExpenseAmt1 = c2.value('(//ExpenseAmt/text())[1]','varchar(MAX)')
, ProgSrvcAccomActy3GrpGrantAmt1 = c2.value('(//GrantAmt/text())[1]','varchar(MAX)')
, ProgSrvcAccomActy3GrpRevenueAmt1 = c2.value('(//RevenueAmt/text())[1]','varchar(MAX)')
, ProgSrvcAccomActy3GrpDesc1 = c2.value('(//Desc/text())[1]','varchar(MAX)')
, ProgSrvcAccomActy3GrpExpenseAmt2 = c2.value('(//ExpenseAmt/text())[2]','varchar(MAX)')
, ProgSrvcAccomActy3GrpGrantAmt2 = c2.value('(//GrantAmt/text())[2]','varchar(MAX)')
, ProgSrvcAccomActy3GrpRevenueAmt2 = c2.value('(//RevenueAmt/text())[2]','varchar(MAX)')
, ProgSrvcAccomActy3GrpDesc2 = c2.value('(//Desc/text())[2]','varchar(MAX)')
, ProgSrvcAccomActy3GrpExpenseAmt3 = c2.value('(//ExpenseAmt/text())[3]','varchar(MAX)')
, ProgSrvcAccomActy3GrpGrantAmt3 = c2.value('(//GrantAmt/text())[3]','varchar(MAX)')
, ProgSrvcAccomActy3GrpRevenueAmt3 = c2.value('(//RevenueAmt/text())[3]','varchar(MAX)')
, ProgSrvcAccomActy3GrpDesc3 = c2.value('(//Desc/text())[3]','varchar(MAX)')
, ProgSrvcAccomActy3GrpExpenseAmt4 = c2.value('(//ExpenseAmt/text())[4]','varchar(MAX)')
, ProgSrvcAccomActy3GrpGrantAmt4 = c2.value('(//GrantAmt/text())[4]','varchar(MAX)')
, ProgSrvcAccomActy3GrpRevenueAmt4 = c2.value('(//RevenueAmt/text())[4]','varchar(MAX)')
, ProgSrvcAccomActy3GrpDesc4 = c2.value('(//Desc/text())[4]','varchar(MAX)')
, ProgSrvcAccomActy3GrpExpenseAmt5 = c2.value('(//ExpenseAmt/text())[5]','varchar(MAX)')
, ProgSrvcAccomActy3GrpGrantAmt5 = c2.value('(//GrantAmt/text())[5]','varchar(MAX)')
, ProgSrvcAccomActy3GrpRevenueAmt5 = c2.value('(//RevenueAmt/text())[5]','varchar(MAX)')
, ProgSrvcAccomActy3GrpDesc5 = c2.value('(//Desc/text())[5]','varchar(MAX)')
, ProgSrvcAccomActy3GrpExpenseAmt6 = c2.value('(//ExpenseAmt/text())[6]','varchar(MAX)')
, ProgSrvcAccomActy3GrpGrantAmt6 = c2.value('(//GrantAmt/text())[6]','varchar(MAX)')
, ProgSrvcAccomActy3GrpRevenueAmt6 = c2.value('(//RevenueAmt/text())[6]','varchar(MAX)')
, ProgSrvcAccomActy3GrpDesc6 = c2.value('(//Desc/text())[6]','varchar(MAX)')
, ProgSrvcAccomActy3GrpExpenseAmt7 = c2.value('(//ExpenseAmt/text())[7]','varchar(MAX)')
, ProgSrvcAccomActy3GrpGrantAmt7 = c2.value('(//GrantAmt/text())[7]','varchar(MAX)')
, ProgSrvcAccomActy3GrpRevenueAmt7 = c2.value('(//RevenueAmt/text())[7]','varchar(MAX)')
, ProgSrvcAccomActy3GrpDesc7 = c2.value('(//Desc/text())[7]','varchar(MAX)')
, ProgSrvcAccomActy3GrpExpenseAmt8 = c2.value('(//ExpenseAmt/text())[8]','varchar(MAX)')
, ProgSrvcAccomActy3GrpGrantAmt8 = c2.value('(//GrantAmt/text())[8]','varchar(MAX)')
, ProgSrvcAccomActy3GrpRevenueAmt8 = c2.value('(//RevenueAmt/text())[8]','varchar(MAX)')
, ProgSrvcAccomActy3GrpDesc8 = c2.value('(//Desc/text())[8]','varchar(MAX)')
, ProgSrvcAccomActy3GrpExpenseAmt9 = c2.value('(//ExpenseAmt/text())[9]','varchar(MAX)')
, ProgSrvcAccomActy3GrpGrantAmt9 = c2.value('(//GrantAmt/text())[9]','varchar(MAX)')
, ProgSrvcAccomActy3GrpRevenueAmt9 = c2.value('(//RevenueAmt/text())[9]','varchar(MAX)')
, ProgSrvcAccomActy3GrpDesc9 = c2.value('(//Desc/text())[9]','varchar(MAX)')
, ProgSrvcAccomActy3GrpExpenseAmt10 = c2.value('(//ExpenseAmt/text())[10]','varchar(MAX)')
, ProgSrvcAccomActy3GrpGrantAmt10 = c2.value('(//GrantAmt/text())[10]','varchar(MAX)')
, ProgSrvcAccomActy3GrpRevenueAmt10 = c2.value('(//RevenueAmt/text())[10]','varchar(MAX)')
, ProgSrvcAccomActy3GrpDesc10 = c2.value('(//Desc/text())[10]','varchar(MAX)')
FROM Form990
CROSS APPLY XMLData.nodes('/Return') AS t(c)
CROSS APPLY XMLData.nodes('//Return//ReturnData//IRS990//ProgSrvcAccomActy3Grp') AS t2(c2);
With a dictionary variable, I would like to check the presence of a key
!$domain_color?={
"technical": "#gray"
}
frame input $INPUT_COLOR {
!if "technical" in $domain_color
ABC -> bad
!else
def -> ok
!endif
How I can do that?
I think it's enough to check the value (!if $domain_color.technical):
#startuml
!$domain_color?={ "technical": "#gray" }
'!$domain_color?={ "fred": "#gray" }
frame input $INPUT_COLOR {
!if $domain_color.technical
ABC -> bad
!else
def -> ok
!endif
#enduml
If you uncomment the line defining fred and comment the line defining technical you can see that your diagram changes.
I have designed a screen using SDA in AS/400 that takes an ID number as input and searches in two PFs for that ID and displays corresponding values fetched from those PFs in the respective fields on screen. Below is the DSPF code:
A*%%TS SD 20180813 084626 PATELDH REL-V7R1M0 5770-WDS
A*%%EC
A DSPSIZ(24 80 *DS3)
A R HEADER
A*%%TS SD 20180802 075026 PATELDH REL-V7R1M0 5770-WDS
A 2 2USER
A 2 30'PRODUCT INQUIRY SCREEN'
A COLOR(WHT)
A 2 63DATE
A EDTCDE(Y)
A 3 63TIME
A R FOOTER
A*%%TS SD 20180802 074433 PATELDH REL-V7R1M0 5770-WDS
A OVERLAY
A 22 4'F3=EXIT'
A R DETAIL
A*%%TS SD 20180813 073420 PATELDH REL-V7R1M0 5770-WDS
A CA03(03 'EXIT')
A CA12(12 'PREVIOUS')
A OVERLAY
A 7 16'ID:'
A 10 16'NAME:'
A 12 16'CATEGORY:'
A #ID R I 7 20REFFLD(CATEGORIES/ID AS400KT2/RCATE-
A GORY)
A #NAME R O 10 22REFFLD(PRODUCTS/NAME AS400KT2/RPROD-
A UCTS)
A #CATEGORY R O 12 26REFFLD(CATEGORIES/CATEGORY AS400KT2-
A /RCATEGORY)
A R MSGSFL SFL
A*%%TS SD 20180803 054959 PATELDH REL-V7R1M0 5770-WDS
A SFLMSGRCD(24)
A MSGKEY SFLMSGKEY
A MSGQ SFLPGMQ(10)
A R MSGCTL SFLCTL(MSGSFL)
A*%%TS SD 20180813 084626 PATELDH REL-V7R1M0 5770-WDS
A OVERLAY
A SFLDSP
A SFLDSPCTL
A SFLINZ
A 01 SFLEND
A SFLSIZ(0002)
A SFLPAG(0001)
A MSGQ SFLPGMQ(10)
I have written a free format RPGLE code that makes this screen work. Below is the RPGLE code:
FDSPPRD CF E WorkStn
FRPRODUCTS IF E K DISK
FRCATEGORY IF E K DISK
FRPRODCATEGO A E K DISK
DtempID S LIKE(ID)
DmsgID S 7A
DmsgF S 10A
D getMsg PR EXTPGM('MSGSFLCL')
D msgID 7A
D msgF 10A
/Free
DoW *In03 = *Off;
Write HEADER;
Write FOOTER;
ExFmt DETAIL;
If #ID = *Zeros;
msgID = 'MSG0001';
msgF = 'ASGNMSGF';
getMsg(msgID:msgF);
Else;
Chain #ID RPRODUCTS;
If %Found(RPRODUCTS);
#NAME = NAME;
Chain ID RCATEGORY;
If %Found(RCATEGORY);
#CATEGORY = CATEGORY;
EndIf;
EndIf;
EndIf;
EndDo;
*InLR = *On;
/End-Free
Below is the CL program called by RPGLE program to get the message text from the msgfile:
PGM PARM(&MSGID &MSGF)
DCL VAR(&MSGID) TYPE(*CHAR) LEN(7)
DCL VAR(&MSGF) TYPE(*CHAR) LEN(10)
SNDPGMMSG MSGID(&MSGID) MSGF(&MSGF)
ENDPGM
Below are the two PFs from which the records are read:
RPRODUCTS-
A R PRODUCTS
A ID 2P 0
A NAME 16A
A K ID
RCATEGORY-
A R CATEGORIES
A ID 2P 0
A CATEGORY 15A
A K ID
All the above codes compile successfully. But the problem is that the msg from the msgf does not appear on the screen. Rest all works. Just the msg from msgf is not being displayed when I press 'Enter' key with a blank ID on screen. Can someone please suggest an information source from where I can learn the concepts of such applications. Also, a help with this one would be appreciated.
You are not writing the MSGCTL record. If you don't write that, then the message subfile will not be displayed. You are also not providing a value for MSGQ.
When using a message subfile, I generally get the program name out of the program status data structure, and put that into MSGQ during program initialization time. It should never change. I also pass that to my procedure that sends the message to the message queue. That way I know that both values will be the same. If they are not the messages will not display.
Here is my message subfile definition:
A* ========================================================================
A* Message Subfile
A* ------------------------------------------------------------------------
A R MSGSFL SFL
A SFLMSGRCD(27)
A MSGKEY SFLMSGKEY
A PGMQ SFLPGMQ(10)
A* ------------------------------------------------------------------------
A* Message Subfile Control
A* ------------------------------------------------------------------------
A R MSGCTL SFLCTL(MSGSFL)
A SFLPAG(1)
A SFLSIZ(2)
A SFLDSP SFLDSPCTL
A SFLINZ
A 53
AON53 SFLEND
A PGMQ SFLPGMQ(10)
There are only a few differences from yours. Lets go through them.
A SFLMSGRCD(27)
This is 27 because I am using the *DS4 screen size. Not an issue.
You are using OVERLAY, I'm not because I write that format first, but as long as you write MSGCTL after you write HEADER you should be good there.
You are using SFLCLR. That is unnecessary, remove it.
A 53
AON53 SFLEND
This is a bit different. I do this because SFLEND requires a conditioning indicator, but I really don't care, I want SFLEND active no matter what that indicator says. (I use *In53 as my SFLEND for regular subfiles too, and I don't want to have to worry whether it is on or off.
I use a sub-procedure to send the message: here is my code for that:
// ----------------------------------------
// SndDspfMsg - sends an *INFO message to the
// message subfile in a display file.
//
// Parameters:
// StackEntry - The program call stack entry to which the message is sent.
// Usually the program name. This must be the same value that
// is placed in the SFLPGMQ variable in the message subfile
// control format.
// MsgId - The Message ID from message file JCMSGF to be sent to the program
// message Queue.
// MsgDta - (optional) Data to be used by the message to provide dynamic
// message content. Defaults to blank.
// MsgDtaLen - (optional) The length of the message data provided above.
// This parameter is required if MsgDta is provided. Defaults
// to zero. If this is not provided or is zero, MsgDta is ignored.
// ----------------------------------------
dcl-proc SndDspfMsg Export;
dcl-pi *n;
StkEnt Char(10) Const;
MsgId Char(7) Const;
MsgDta Char(512) Const Options(*VarSize: *NoPass);
MsgDtaLen Int(10) Const Options(*NoPass);
end-pi;
dcl-s Name_t Char(10) Template Inz('');
// Call Stack Qualifier - used by message handling APIs
dcl-ds CallStackQual_t Qualified Template Inz;
Module Like(Name_t) Inz('*NONE');
Program Like(Name_t) Inz('*NONE');
end-ds;
// Qualified Name
dcl-ds QualName_t Qualified Template Inz;
Name Like(Name_t) Inz('');
User Like(Name_t) Inz('');
end-ds;
// Standard Error Code Format
dcl-ds ErrorCdType1_t Qualified Template Inz;
BytesProv Int(10) Inz(%size(ErrorCdType1_t));
BytesAvail Int(10);
MsgId Char(7);
Data Char(1024) Pos(17);
end-ds;
dcl-ds MsgFile LikeDs(QualName_t) Inz(*LikeDs);
dcl-ds ErrorCd LikeDs(ErrorCdType1_t) Inz(*LikeDs);
dcl-s pmMsgDta Char(512) Inz('');
dcl-s pmMsgDtaLen Int(10) Inz(0);
dcl-s pmMsgTyp Char(10) Inz('*INFO');
dcl-s pmStkCnt Int(10) Inz(0);
dcl-s pmMsgKey Char(4) Inz('');
// Send Program Message
dcl-pr qmhsndpm ExtPgm('QMHSNDPM');
MessageId Char(7) Const;
MessageFile LikeDs(QualName_t) Const;
MessageDta Char(512) Const Options(*Varsize);
MessageLen Int(10) Const;
MessageType Char(10) Const;
StackEntry Char(4102) Const Options(*Varsize);
StackCounter Int(10) Const;
MessageKey Char(4);
Error LikeDs(ErrorCdType1_t);
StackEntryLen Int(10) Const Options(*NoPass);
StackEntryQual LikeDs(CallStackQual_t)
Const Options(*NoPass);
ScreenWaitTime Int(10) Const Options(*NoPass);
StackEntryType Char(10) Const Options(*NoPass);
Ccsid Int(10) Const Options(*NoPass);
end-pr;
// Handle *NoPass Parms
if %parms() >= %parmnum(MsgDtaLen);
pmMsgDtaLen = MsgDtaLen;
endif;
// if Message Data is provided,
if pmMsgDtaLen > 0;
pmMsgDtaLen = min(%size(pmMsgDta): pmMsgDtaLen);
pmMsgDta = %subst(MsgDta: 1: pmMsgDtaLen);
endif;
MsgFile.Name = 'JCMSGF';
qmhsndpm(MsgId: MsgFile: pmMsgDta: pmMsgDtaLen:
pmMsgTyp: StkEnt: pmStkCnt: pmMsgKey:
ErrorCd);
end-proc;
This should get your message subfile working. As for why the other fields are not populating, maybe your product ID and category ID are not found in the file. Note, the product ID and category ID will be the same value when this program runs because ID is mapped to the display file, the product file, and the category file. This doesn't seem to be what you want. If you have trouble dealing with that, ask a new question.
Can someone please tell me a 'general use', step-by-step method to find out what are the non-aggregability fields in a datamart. Here an example I found:
Notes: italic means 'key', bold identifies 'shortenings', 'column' is an alias for 'referencing'
Relational schema:
CALL(COD,DATE,FROM:S,TO:S,LEN)
SIM(SIM, USER:USER, TRIFF:T, BONUS)
TARIFF(TARIFF, CARRIER:CAR)
USER(USER, TOWN:TOW, LAST_TARIFF:TAR)
ROAMING_CALL(COD:CAL, FOREIGN_CARRIER:CAR)
PROMO_CALL(COD:CAL, PROMO_TARIFF:P_TA)
PROMO_TARIFF(TARIFF:TAR)
TOWN(TOWN,NATION)
CARRIER(CARRIER, NATION)
REQUESTS:
build a fact-schema for 'CALL' with following
dimensions:
DATE, SIM_FROM, CALLED_CARRIER, FOREIGN_CARRIER, PROMO_TARIFF and
measures: AVG_CALL_LENGTH, NUM_OUTGOING_SIM (as count distinct FROM),
NUM_INCOMING_SIM (as count distinct TO)
Now I can draw the fact-schema, but I'm in trouble finding what measures are aggregable along which dimensions
EDIT:
this is the pdf for the fact schema I have (sorry for not using a strict sintax but reading notes are included)
Measures:
Standard [obtained by the operational schema]:
NUM_INCOMING_CALLS = COUNT DISTINCT (TO)
UN-AGGREGABILITIES ->*THIS IS MY ISSUE*
Calculated [obtained by the operational schema, need partial data to add properly]:
AVG_CALL_LENGTH = CL_SUM/CL_COUNT
where
CL_SUM = SUM (LENGTH), CL_COUNT = COUNT(LENGTH)
UN-AGGREGABILITIES ->*THIS IS MY ISSUE*
Derived [can be found as a dimension]:
NUM_OUTGOING_CALLS = COUNT DISTINCT ( FROM )
UN-AGGREGABILITIES ->*THIS IS MY ISSUE*
Ok, I went and asked my teacher: he gave me a easy algorithm:
Given a schema D{D1, D2, D3, ... Dn}, for a Mesaure M= count distinct A n
if A U X -> Di is not trivial, X subset of D
X U A -> D1 (True)
X U A -> D2 (False)
X U A -> D3 (True)
...
X U A -> Dn-1 (False)
I have that NA = {D2, Dn-1}
NA: set of non-aggregabilities