Struct dynamic addressing syntax

Will provide the example to illustrate -- have two field names, say 'Income' and 'Expense' which are subaccounts of many parent accounts in a large table. The need is to locate the row positions of eac account subaccount and return in a struct an array of those locations. It is known the bounds of the main account for each as an array of indices, ix to the first/last record in the table. It is then easy to use that knowledge to find the two rows; a syntax such as
[i1,i2]=find(matches(table2array(tB(ix(1):ix(2),1:3)),flds));
S.(flds)=find(i1);
would be ideal IF (the provervbial "big if") the order of i1 above matched the position of the two field names in the order in which they happen to occur in the table (this is an application interacting with a Quickbooks database exported to Excel; the user can either deliberately or accidentally cause QB to reorder the fund order to alphabetical instead so it cannot be assumed the order is fixed). A 'stable' option on the matches function similar to unique would be most helpful here.
If that issue is resolved, then it would seem should be possible to assign the array of indices to the array of field names in the struct but I've found no syntax that will work to do that. The latter may simply be that I've not used MATLAB structures with more than the most naively written syntax owing to I've always run into something similar to this that has always frustrated me and caused me to use some other storage strategem(*). So, now with a specific example, thought I'd throw it for discussion...
(*) For now, I've reverted to the simple for...end loop over the fieldnames but it just seemed as though something like the original should be doable.

6 Comments

Will provide the example to illustrate -- have two field names, say 'Income' and 'Expense' which are subaccounts of many parent accounts in a large table.
This isn't clear to me. Do you have a struct array, a table array, a struct containing a table, a table containing a struct, two variables, or some other combination?
And if you're using a struct array do you have an array of structs or a struct with fields that are arrays? Which way the data is "sliced" will impact how easy it is to access data from a subset of its elements and/or fields.
D = 1:5;
C = num2cell(D);
arrayOfStructs = struct('x', C)
arrayOfStructs = 1×5 struct array with fields:
x
structWithArray = struct('x', D)
structWithArray = struct with fields:
x: [1 2 3 4 5]
Can you show us a (small) concrete minimal working example?
The struct is a single struct containing the index arrays to the pieces of the puzzle that can use to address individual subaccounts by account (and month). I can show you my desired result for a given (relatively) small input table; the real thing is several times as long.
The other rub is there are two separate QB databases at the present--the reason still need the external code until can get merged/transitioned to new accounting system; this is just an intermediary crutch to make the transition for the local community college foundation for which I've been doing this background work pro bono for last couple years with the help of MATLAB to deal with the original mess of some hundreds of individual Excel workbooks...the transitioning of those into a QB database has been the first step.
Anyways; the problem is there is a structural difference between the two databases so that not only are the orders of the subaccounts not always the same, the table columns containing the data fields of interest are not the same because there are different levels of subaccounts between the two owing to the differences in the types of funds and requirements to keep certain funds separate to meet donor or investment requirements. Hence the very complicated structure of the attached function that does serve the purpose, just would be nicer to be cleaner.
Attached is a sample of the misc-designated funds table which has the income/expense subaccounts; the other table contains the restricted/permanent designated funds which have Corpus, Realized, Unrealized G/L subaccounts instead.
Also attached is the struct for the above table generated by the existing code; it works but is a nightmare to maintain, the particular point raised in the Q? above is in the otherwise clause of the function; not sure there's much that can be done about the other logic to deal with the rearrangement between columns and investment types...
The struct looks like
>> S=fundRange(tQB,'Class','61500')
S =
struct with fields:
Range: [2×1 double]
Addends: [13×1 double]
FundAddends: [13×2 double]
FundTotals: [13×1 double]
Income: [13×1 double]
Expense: [13×1 double]
Total: 77.00
>>
from the above each month can iterate over the size of the Addends array and compute with those indices the new balances and post them to the table and output to an Excel table for inspection before generating the IIF import file to post to the actual database. The issue this resolves is allowing for the input postings to be reviewed by management before being posted to the real accounting database; the allocation of donations to donor funds, etc., may not be made correctly by the data entry persons from the short and sometimes cryptic notes on the deposit slips as to purpose. (The new system will have that ability built in but in the intermediate time, there isn't any facility available for such review; consequently extra work is then required when the mistakes are uncovered to make correcting journal entries, etc., etc., ...)
fundRange can also be called with a fund donor name instead of an account number or with an individual fund in which case it returns the same fields for just the specific fund(s).
Sorry, had a misslip on the posting -- didn't realize it and ended up with two copies of some -- they're the same thing, just a mistake.
Peter Perkins
Peter Perkins on 12 Dec 2022
Edited: Peter Perkins on 12 Dec 2022
Also it looks like those mat files are your whole workspace? I was gonna assume that the only thing of interest in tQB.mat is tQB, and S in S.mat, but then I saw "the other table contains the restricted/permanent designated funds which have Corpus, Realized, Unrealized G/L subaccounts instead" so there's another table somewhere.
dpb, like Steve, I'm having trouble understanding the questions. Especially I'm not following
"A 'stable' option on the matches function similar to unique would be most helpful here", because matches returns a logical the same size as its first input, so in that sense, it is stable.
and
"assign the array of indices to the array of field names in the struct". You have a scalar struct, and there's no simple way to assign to multiple fields of a struct in one assignment (one of the reasons tables are often a better choice than struct for data that can be flattened).
Sorry @Peter Perkins, I didn't do a good job at trying to make up a test case; too much time pressure to get results to the auditors that I didn't get back until now to even look...
I'll have to go back and see where/how the issue regarding ordering after the matches operation was an issue; that may have been a red herring that I didn't realize what had happened in the QB database about it having rearranged fields yet at the time...
I think the result to the Q? is in your last comment above "You have a scalar struct, and there's no simple way to assign to multiple fields of a struct in one assignment". That's the crux of what I was driving at because the result of the match is an array and storing those elements was what I was struggling with finding a convenient syntax for.
The overall structure is a table; this struct is a supporting data indexing structure that is the result of the lookup function, the fields of which are used to reference into the table by given rows across a group of individual funds. It has fields that are the components and the total for either a specific fund or across a group of funds which comprise either a single donor fund that may have multiple investment pieces or across a multitude of donor funds which comprise an "investment pool" across which investment earnings are allocated.
I used the struct there to have a concise mechanism in which to hold the indices to various pieces-parts that need for updating the table; it's possible a redesign there might be beneficial towards solving that problem. But, the main code now uses the struct and so it would take rewriting it to be able to make use of a different storage scheme for these...
The data are now at the auditors; I did get that completed; it's on to the large scholarship billing coding at the moment that is the present crisis. It provides the data against which of the various donor funds expenses are allocated to provide those to the students...and the cycle repeats.

Sign in to comment.

Answers (0)

Categories

Find more on Historical Contests in Help Center and File Exchange

Products

Asked:

dpb
on 30 Nov 2022

Commented:

dpb
on 17 Dec 2022

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!