Creating lists in google sheets - google-sheets

Wasn't really sure how else to word the title, but here's a little more information!
In this spreadsheet: https://docs.google.com/spreadsheets/d/1oXLbc9vkjuWYU60xhsYsT3vv7utOJswVjwJUWS3XpF0/edit?usp=sharing
In the 'Lists by Item Type' sheet, I would like to make lists of all the items separated by item types for use in data validation elsewhere. Is there a function similar to =UNIQUE() that will give me a list of all items with the value x in column Q where x is the item type I input?

Use:
=FILTER(
/* all item names ('Item Database'!$A$3:$A) */,
/* all item types ('Item Database'!$Q$3:$Q) */ = /* the needed item type */
)
This will give you all the items of a given type.

Related

Sorting rows in a Grid column of String type based on corresponding integer values

I have the following structure for a Grid and wanted to know how to sort a column based on the Integer values of the Strings. The data provider is not flexible to change, so I have to sort with some kind of intermediary step:
Grid<String[]> grid = new Grid<>();
...
grid.addColumn(str -> str[columnIndex]).setHeader("sample").setKey("integercolumn").setSortable(true);
...
GridSortOrder<String> order = new GridSortOrder<>(grid.getColumnByKey("integercolumn"), SortDirection.DESCENDING);
grid.sort(Arrays.asList(order));
This sorts two digit numbers properly but not one digit or 3+.
You can define a custom comparator on the column that is used for sorting its values. In your case the comparator needs to extract the column-specific value from the array, and then convert it to an int:
grid.addColumn(row -> row[columnIndex])
.setHeader("sample")
.setKey("integercolumn")
.setSortable(true)
.setComparator(row -> Integer.parseInt(row[columnIndex]));
See https://vaadin.com/docs/latest/components/grid/#specifying-the-sort-property.

How can I find the first instance (searching up) of a value in a column?

Picture linked below as this is a bit tangled:
I am working with a data set that has "nested" values. There are three different types of entries: categories, then subcategories that are nested under the categories, then individual items that are nested under the subcategories (picture linked below). The entries are matched up using a filter system. Column A has the entry type, column B has the actual value, column C has the filter. The filter is always the value of entry you are nesting under. So, for a subcategory entry, Column A= "Subcategory", Column B= [name of subcategory] Column C = Column B of the category type entry above (the name of category it belongs to).
I need a way to automatically fill in the filters.
The way I am thinking I could do this is to search Column A (moving up) for the first instance of the entry type I need, and then return the value of the Column B cell in that row. Is this possible?
Given your exact data above (looking only at A14:C), delete everything from C14:C (including the header) and place the following formula in C14:
=ArrayFormula({"FILTER"; IF((A15:A="") + (A15:A="Category"),, IF(A15:A="Subcategory", VLOOKUP(ROW(A15:A), FILTER({ROW(A15:A), B15:B}, A15:A="Category"), 2, TRUE), VLOOKUP(ROW(A15:A), FILTER({ROW(A15:A), B15:B}, A15:A="Subcategory"), 2, TRUE)))})
This will create the title (which you can edit within the formula itself as you like) and all results for non-null rows thereafter.
You'll need to adjust the 15 in ranges to whatever the starting row of your non-header data actually is in your sheet.

How do i remove rows based on comma-separated list of values in a Power BI parameter in Power Query?

I have a list of data with a title column (among many other columns) and I have a Power BI parameter that has, for example, a value of "a,b,c". What I want to do is loop through the parameter's values and remove any rows that begin with those characters.
For example:
Title
a
b
c
d
Should become
Title
d
This comma separated list could have one value or it could have twenty. I know that I can turn the parameter into a list by using
parameterList = Text.Split(<parameter-name>,",")
but then I am unsure how to continue to use that to filter on. For one value I would just use
#"Filtered Rows" = Table.SelectRows(#"Table", each Text.StartsWith([key], <value-to-filter-on>))
but that only allows one value.
EDIT: I may have worded my original question poorly. The comma separated values in the parameterList can be any number of characters (e.g.: a,abcd,foo,bar) and I want to see if the value in [key] starts with that string of characters.
Try using List.Contains to check whether the starting character is in the parameter list.
each List.Contains(parameterList, Text.Start([key], 1)
Edit: Since you've changed the requirement, try this:
Table.SelectRows(
#"Table",
(C) => not List.AnyTrue(
List.Transform(
parameterList,
each Text.StartsWith(C[key], _)
)
)
)
For each row, this transforms the parameterList into a list of true/false values by checking if the current key starts with each text string in the list. If any are true, then List.AnyTrue returns true and we choose not to select that row.
Since you want to filter out all the values from the parameter, you can use something like:
= Table.SelectRows(#"Changed Type", each List.Contains(Parameter1,Text.Start([Title],1))=false)
Another way to do this would be to create a custom column in the table, which has the first character of title:
= Table.AddColumn(#"Changed Type", "FirstChar", each Text.Start([Title],1))
and then use this field in the filter step:
= Table.SelectRows(#"Added Custom", each List.Contains(Parameter1,[FirstChar])=false)
I tested this with a small sample set and it seems to be running fine. You can test both and see if it helps with the performance. If you are still facing performance issues, it would probably be easier if you can share the pbix file.
This seems to work fairly well:
= List.Select(Source[Title], each Text.Contains(Parameter1,Text.Start(_,1))=false)
Replace Source with the name of your table and Parameter1 with the name of your Parameter.

How can I iterate over list items in Pandoc's lua-filter function?

Pandoc's lua filter makes it really easy to iterate over a document and munge the document as you go. My problem is I can't figure out how to isolate list item elements. I can find lists and the block level things inside each list item, but I can't figure out a way to iterate over list items.
For example let's say I had the following Markdown document:
1. One string
Two string
2. Three string
Four string
Lets say I want to make the first line of each list item bold. I can easily change how the paragraphs are handled inside OrderedLists, say using this filter and pandoc --lua-filter=myfilter.lua --to=markdown input.md
local i
OrderedList = function (element)
i = 0
return pandoc.walk_block(element, {
Para = function (element)
i = i + 1
if i == 1 then return pandoc.Para { pandoc.Strong(element.c) }
else return element end
end
})
end
This will indeed change the first paragraph element to bold, but it only changes the first paragraph of the first list item because it's iterating across all paragraphs in all list items in the list, not on each list item, then on each paragraph.
1. **One string**
Two string
2. Three string
Four string
If I separate the two list items into two separate lists again the first paragraph of the first item is caught, but I want to catch the first paragraph of every list item! I can't find anything in the documentation about iterating over list items. How is one supposed to do that?
The pandoc Lua filter docs have recently been updated with more info on the properties of each type. E.g., for OrderedList elements, the docs should say (it currently says items instead of content, which is a bug):
OrderedList
An ordered list.
content: list items (List of Blocks)
listAttributes: list parameters (ListAttributes)
start: alias for listAttributes.start (integer)
style: alias for listAttributes.style (string)
delimiter: alias for listAttributes.delimiter (string)
tag, t: the literal OrderedList (string)
So the easiest way is to iterate over the content field and change items therein:
OrderedList = function (element)
for i, item in ipairs(element.content) do
local first = item[1]
if first and first.t == 'Para' then
element.content[i][1] = pandoc.Para{pandoc.Strong(first.content)}
end
end
return element
end

Append new ListItem to particular list in Google Docs API

I'm looking for a way to append new ListItem to particular list in Google Docs API.
My problem is that I can't figure out how to determine last item in list, so I could just insert new item using it's index.
My vision of how to implement this looks like:
body.insertListItem(body.getChildIndex(lastItem) + 1, newItem);
P.S. Am I doing something wrong, maybe there is some other way to implement appending?
Thanks in advance!
A ListItem is a Paragraph that is associated with a list ID. A ListItem may contain Equation, Footnote, HorizontalRule, InlineDrawing, InlineImage, PageBreak, and Text elements. For more information on document structure, see the guide to extending Google Docs.
ListItems with the same list ID belong to the same list and are numbered accordingly. The ListItems for a given list are not required to be adjacent in the document or even have the same parent element. Two items belonging to the same list may exist anywhere in the document while maintaining consecutive numbering, as the following example illustrates:
var body = DocumentApp.getActiveDocument().getBody();
// Append a new list item to the body.
var item1 = body.appendListItem('Item 1');
// Log the new list item's list ID.
Logger.log(item1.getListId());
// Append a table after the list item.
body.appendTable([
['Cell 1', 'Cell 2']
]);
// Append a second list item with the same list ID. The two items are treated as the same list,
// despite not being consecutive.
var item2 = body.appendListItem('Item 2');
item2.setListId(item1);

Resources