Assigning a value to merged cells in Apple Numbers using AppleScript - applescript

As part of a longer AppleScript, I'm copying strings from a list variable into ranges of merged cells in a Numbers 10.0 table. E.g., if the list is called form_filler and the first range of merged cells is B6:Y7, I first tried:
set value of cell "B6" to item 1 of form_filler
I thought one addresses merged cells by the top-left cell. But this does something unexpected: it places the string only into cell "B6" and changes the range of merged cells to C6:Y7, excluding the cell I just pasted into. This behavior occurs consistently with different merged cells throughout the table. I then tried:
set value of range "B6:Y7" to item 1 of form_filler
but this returned an error; I can't assign a value to the range.
I'm new to AppleScript, but not programming generally (e.g., Python). What am I missing? Thanks.

It looks like you have to re-merge those cells. Here's code I just tested using my own tell block structure; you should be able to extrapolate from this (if you include your tell block structure I'll edit my code):
tell application "Numbers"
set d to sheet 1 of document 1
tell d
set value of cell "B6" of table 1 of it to "test"
merge range "B6:Y7" of table 1 of it
end tell
end tell
Not sure if this qualifies as a "work-around", but it seems to work, hopefully w/o introducing other issues.

Related

Reporting Multiple Values & Sorting

Having a bit of an issue and unsure if it's actually possible to do.
I'm working on a file that I will enter target progression vs actual target reporting the % outcome.
PAGE 1
¦NAME ¦TAR 1 %¦TAR 2 %¦TAR 3 %¦TAR 4 %¦OVERALL¦SUB 1¦SUB 2¦SUB 3¦
¦NAME1¦ 114%¦ 121%¦ 100%¦ 250%¦ 146%¦ 2¦ 0¦ 0%¦
¦NAME2¦ 88%¦ 100%¦ 90%¦ 50%¦ 82%¦ 0¦ 1¦ 0%¦
¦NAME3¦ 82%¦ 54%¦ 64%¦ 100%¦ 75%¦ 6¦ 6¦ 15%¦
¦NAME4¦ 103%¦ 64%¦ 56%¦ 43%¦ 67%¦ 4¦ 4¦ 24%¦
¦NAME5¦ 87%¦ 63%¦ 89%¦ 0%¦ 60%¦ 3¦ 2¦ 16%¦
Now I already have it sorting all rows by the Overall % column so I can quickly see at a glance but I am creating a second page that I need to reference points.
So on the second page I would like to somehow sort and reference different columns for example
PAGE 2
TOP TAR 1¦Name of top %¦Top %¦
TOP TAR 2¦Name of top %¦Top %¦
Is something like this possible to do?
Essentially I'm creating an Employee of the Month form that automatically works out who has topped what.
I'm willing to drop a paypal donation for whoever can figure this out for me as I've been doing it manually every month and would appreciate the time saved
I don't think a complicated array formula is necessary for this - I am suggesting a fairly standard Index/Match approach.
First set up the row titles - you can just copy and transpose them from Page 1, or use a formula in A2 of Page 2 like
=transpose('Page 1'!B1:E1)
The use them in an index/match to get the data in the corresponding column of the main sheet and find its maximum (in C2)
=max(index('Page 1'!A:E,0,match(A2,'Page 1'!A$1:E$1,0)))
Finally look up the maximum in the main sheet to find the corresponding name:
=index('Page 1'!A:A,match(C2,index('Page 1'!A:E,0,match(A2,'Page 1'!A$1:E$1,0)),0))
If you think there could be a tie for first place with two or more people getting the same score, you could use a filter to get the different names:
So if the max score is in B8 this time (same formula)
=max(index('Page 1'!A:E,0,match(A8,'Page 1'!A$1:E$1,0)))
the different names could be spread across the corresponding row using transpose (in C8)
=ArrayFormula(TRANSPOSE(filter('Page 1'!A:A,index('Page 1'!A:E,0,match(A8,'Page 1'!A$1:E$1,0))=B8)))
I have changed the test data slightly to show these different scenarios
Results

Google Sheets COUNTIF syntax across different tabs

I am currently trying to work out how to make the current Google Sheets version of COUNTIF properly count how many times the value of a cell (C3) is higher than the value if another cell (E3), according to the following formula:
=COUNTIF('4'!$C$3,">'4'!$E$3")
You'll note that the formula is run in a different tab than the one where the cells being counted are located in (which is named "4"). The formula returns a zero '0', when it should be returning a one '1', as the value in '4'!$C$3 actually is higher than the value in '4'!$E$3.
Clearly, I am doing something wrong.
So, the user I'-'I (stackoverflow.com/users/8404453/i-i) suggested the following edit:
=COUNTIF('4'!$C$3,">'4'!$E$3") --> COUNTIF('4'!$C$3,">"&'4'!$E$3)
This suggestion resolved my issue.

Picking random cells based on previous random cell selection in Excel

This formula works well to return a random traveldestination1 value if it does find a match for C1 in the moderange range. It goes to #N/A otherwise:
=IF(MATCH(C1,moderange1,0),INDEX(traveldesination1,RANDBETWEEN(1,COUNTA(traveldesination1))),"nope")
How can I improve the formula to search another moderange range (non-adjacent) if a match for C1 is not found in moderange1 (it returns #N/A) (or moderange2 or moderange3 etc...)? It never actually gets to the point of displaying “nope” in this current formula so any code I add there doesn’t get used.
If it doesn't find a match in moderange1, I want it to search moderange2 and if it finds a match there, it should pick a random from traveldestination2 and so on.
I've managed to figure it out! - using nested IFNA conditions did the trick:
=ifna(ifna(ifna(code as above),next range's code, next range's code),"not found")

Ruby Axlsx Gem Unlocking style on whole column

Using Ruby with the gem axlsx I've been trying to figure out how to set a style for an entire column and I haven't yet found it. The only way I've been able to do this is in a loop, setting each cell in the row to have the style I'd like, e.g.:
unlocked = wb.styles.add_style :locked => false
#...looping code here, assuming add_worksheet has been assigned to sheet
sheet.rows[rowNum].cells[columnNum].style = unlocked
I found out how to set a hidden attribute to an entire column:
sheet.column_info[3].hidden = true
And from the documentation I had thought this line would work:
sheet.column_info[0].style = unlocked
The strangest thing is that this style set line does not fail to apply and indeed querying it after looks to show the style is set to the corresponding number from the add_style return. However, on checking the produced spreadsheet it doesn't show the whole column as unlocked.
I know this can be done on a whole column quite easily using the write_xlsx gem so I wondered if it can be done using axlsx and I just can't find examples of the right syntax to use?
To do this you can use Worksheet#col_style signature is col_style(index,style,options={})
index
The index of the row you want to set the style on (indexing starts at 0). Also index can be a range so if you want to unlock columns A though C then sheet.col_style((0..2),unlocked) will still work appropriately based on the way the code functions.
style
must be a predefined style as it is in the rest of the gem
options ={}
options allows you to set a row offset so if you didn't want to unlock the top n rows you could pass row_offset: n and all the cells in the column after n rows would be unlocked.
Example:
#unlock cells in column A starting at A3
sheet.col_style(0,unlocked,row_offset: 2)
Full Example
require 'axlsx'
p = Axlsx::Package.new
wb = p.workbook
unlocked = wb.styles.add_style(locked: false)
wb.add_worksheet do |sheet|
5.times { sheet.add_row [1,2,3,4,5,6]}
sheet.col_style(3,unlocked)
end
p.serialize('/simple_test.xlsx')
This will create a spreadsheet with 6 columns and the column with 4's (indexing starts at 0) will be unlocked while the rest of the columns remain locked (default).
Additional Info
The return value from this method will be a flat Array of the cells affected.
Note: the code does pretty much exactly what you are doing in your loop. It collects all the cells and then applies the style to each cell in a loop.

Excel Force Calculation

I have a cell that is evaluated by
=IF(OR(J41="",J40=""),"",(1-($J$41/$J$40)))
computing the percent error between two cells that the user inputs. Additionally, I have an IFC on a seperate sheet that is validating this cell, among other cells, and setting it to a certain color with a warning if the percent error value is above/below a certain number. The problem is that the cell does not show the warning unless I click on it and hit enter (or F2 + Enter), which calculates the cell and populates the value at that time. Is there a way to Force the calculation to occur in that cell when the user inputs values into J41 and J40, thus populating the warning immediately? I have checked multiple threads on this, some say use the Application.Volatile statement, but I am not too sure if that will work..
Any suggestions?
Manually calculating a range is as simple as using Range.Calculate.
To run code when a value is changed in a certain range, use Worksheet_Change.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngTrigger As Range: Set rngTrigger = Range("D5")
Dim rngTarget As Range: Set rngTarget = Range("E5")
If Not Intersect(Target, rngTrigger) Is Nothing Then _
rngTarget.Calculate
End Sub

Resources