OpenOffice calc, can macros update cell content automatically? - openoffice-calc

I have used a macro I found on a forum online.
It detects the background colour of a indicated cell and returns a numerical value of that background colour. The problem is that it does it only once. When I change the background colour of the indicated cell, the numerical value does not update.
To update it I have to change something in the cell where I call on the macro (e.g. delete one character and retype it), and hit enter. Then it updates the numerical value.
Is there a way to get it to update automatically? Alternatively, is there an easier way to get it to update (compared to the described deleting and retyping method), preferably one that works on multiple cells at once.
Code by Villeroy at openoffice forum:
Function CELL_BACKCOLOR(vSheet,lRowIndex&,iColIndex%)
'calls: getSheetCell
REM returns color code as number
Dim v
v = getSheetCell(vSheet,lRowIndex&,iColIndex%)
if vartype(v) = 9 then
CELL_BACKCOLOR = v.CellBackColor
else
CELL_BACKCOLOR = v
endif
End Function
Function getSheetCell(byVal vSheet,byVal lRowIndex&,byVal iColIndex%)
dim oSheet
' print vartype(vsheet)
oSheet = getSheet(vSheet)
if varType(oSheet) <>9 then
getSheetCell = NULL
elseif (lRowIndex > oSheet.rows.count)OR(lRowIndex < 1) then
getSheetCell = NULL
elseif (iColIndex > oSheet.columns.count)OR(iColIndex < 1) then
getSheetCell = NULL
else
getSheetCell = oSheet.getCellByPosition(iColIndex -1,lRowIndex -1)
endif
End Function

I'm not sure why the "AutoCalculate" setting doesn't work in this case (tested with LibreOffice 7.0.2). Anyway, you can manually update the macro output for a single cell or for multiple cells:
for a single cell, hit F9
for multiple cells, select them and hit CTRL + SHIFT + F9.

Related

Excel, duplicates in string, single cell iteration

I'm trying to extract certain pieces of data from a very long string within a single cell. For the sake of this exercise, this is the data I have in cell A1.
a:2:{s:15:"info_buyRequest";a:5:{s:4:"uenc";s:252:"WN0aW9uYWwuaHRlqdyZ2dC1hdD0lN0JhZHR5cGUlN0QmdnQtcHRpPSU3QmFkd29yZHNfcHJvZHVjdHRhcmdldGlkJTdEJiU3Qmlnbm9y,";s:7:"product";s:4:"1253";s:8:"form_key";s:16:"wyfg89N";s:7:"options";a:6:{i:10144;s:5:"73068";i:10145;s:5:"63085";i:10141;s:5:"73059";i:10143;s:5:"73064";i:13340;s:5:"99988";i:10142;s:5:"73063";}s:3:"qty";s:1:"1";}s:7:"options";a:6:{i:0;a:7:{s:5:"label";s:5:"Color";s:5:"value";s:11:"White";s:11:"print_value";s:11:"White";s:9:"option_id";s:5:"10144";s:11:"option_type";s:9:"drop_down";s:12:"option_value";s:5:"73068";s:11:"custom_view";b:0;}i:1;a:7:{s:5:"label";s:4:"Trim";s:5:"value";s:11:"Black";s:11:"print_value";s:11:"Black";s:9:"option_id";s:5:"10145";s:11:"option_type";s:9:"drop_down";s:12:"option_value";s:5:"63085";s:11:"custom_view";b:0;}i:2;a:7:{s:5:"label";s:7:"Material";s:5:"value";s:15:"Vinyl";s:11:"print_value";s:15:"Vinyl";s:9:"option_id";s:5:"10141";s:11:"option_type";s:9:"drop_down";s:12:"option_value";s:5:"73059";s:11:"custom_view";b:0;}i:3;a:7:{s:5:"label";s:6:"Orientation";s:5:"value";s:17:"Left Side";s:11:"print_value";s:17:"Left Side";s:9:"option_id";s:5:"10143";s:11:"option_type";s:9:"drop_down";s:12:"option_value";s:5:"73064";s:11:"custom_view";b:0;}i:4;a:7:{s:5:"label";s:12:"Table";s:5:"value";s:16:"YES! Add Table";s:11:"print_value";s:16:"YES! Add Table";s:9:"option_id";s:5:"13340";s:11:"option_type";s:9:"drop_down";s:12:"option_value";s:5:"99988";s:11:"custom_view";b:0;}i:5;a:7:{s:5:"label";s:8:"Shipping";s:5:"value";s:20:"Front Door Delivery";s:11:"print_value";s:20:"Front Door Delivery";s:9:"option_id";s:5:"10142";s:11:"option_type";s:9:"drop_down";s:12:"option_value";s:5:"73063";s:11:"custom_view";b:0;}}}
The end result, would be to separate the values for Color, Trim, Material Orientation, etc.
The formula I was using is this:
=MID(LEFT(A4,FIND("print_value",A4)-9),FIND("Color",A4)+25,LEN(A4))
This basically looks in between two points and trims out the fat. It works, but only for the first iteration of "print_value". If I were to use this searching for "Trim"...
=MID(LEFT(A4,FIND("print_value",A4)-9),FIND("Trim",A4)+25,LEN(A4))
...I get an empty result. This happens because print_value is duplicate and not unique to the string. Excel doesn't understand what point to apply its function to and poops itself.
Even though there are unique factors within this string that I could essentially attach myself to (and arrive at the desired result), I CAN NOT use them as they will not be consistent and will render the formula useless when applied to other cells.
That said, here is what I need. Within this formula, I need a way to either A) tell the formula which iteration of print_value to find or B) change print_value to print_value(1,2,3,4, etc) and then run my trimming formula.
Few options based on this link:
1) VBA - Using a User Defined Function
If you're new to these then follow this tutorial.
Function FindN(sFindWhat As String, _
sInputString As String, N As Integer) As Integer
Dim J As Integer
Application.Volatile
FindN = 0
For J = 1 To N
FindN = InStr(FindN + 1, sInputString, sFindWhat)
If FindN = 0 Then Exit For
Next
End Function
2) Using a Formula
=FIND(CHAR(1),SUBSTITUTE(A1,"c",CHAR(1),3))
c is the character you want to find
A1 is the text you want to look in
3 is the nth instance

This cell duplicates image in that cell in spreadsheet?

Very simple. Cell A1 has an image in it, which I supply through Insert:Picture:From File...
Now I want Cell A3 to automatically show the same picture. I simply can't find a way-- certainly the "=" doesn't work. At this point, I don't care if the images are "links" or embedded, I just want it to work. Can it? Thx.
Edit, 09-01-17, based on Jim K's idea, here's macro code I have installed:
REM ***** BASIC *****
Private oListener as Object
Private cellA1 as Object
Sub AddListener
Dim Doc, Sheet, Cell as Object
Doc = ThisComponent
Sheet = Doc.Sheets.getByName("Sheet1")
cellA1 = Sheet.getCellrangeByName("A1")
'create a listener
oListener = createUnoListener("Modify_","com.sun.star.util.XModifyListener")
'register the listener
cellA1.addModifyListener(oListener)
End Sub
Sub Modify_disposing(oEv)
End Sub
Sub RmvListener
cellA1.removeModifyListener(oListener)
End Sub
' macro jumps here when oListener detects modification of Sheet
Sub Modify_modified(oEv)
Doc = ThisComponent
Sheet = Doc.Sheets.getByIndex(0)
originCell = Sheet.getCellByPosition(0,0)
originValue = originCell.Value
if originValue then
print "originValue is " & originValue
else
print "originValue zero"
end if
End Sub
The problem, ironically, is that it works. It works for integers and {non-value}, I mean an empty cell.
So any integer not zero prints TRUE, zero prints FALSE, and empty cell prints FALSE.
But that's where it quits working-- any kind of string "asdf" also returns FALSE.
Maybe that could be fixed, but there's something a lot worse: When I paste an image in the cell, or use the Insert/Image/From File... menu, or Cut an existing image... Nothing happens! The Sheet Modified business does not trigger the expected routine.
Any hope? Thx.
As you discovered, the solution in my comment does not work, because the Content changed event will not trigger when images are added. I looked into other events as well, but they did not work either.
So instead, we can set up a function that runs periodically. Each time it runs, it checks the count of images, and if any have been added or removed, it calls update_copied_images() below, which currently simply reports the value of cell A1, as in your code.
As explained here, I have not gotten a timer loop to work in Basic without crashing, so we can use Python instead (a better language, so this is not a drawback in my opinion).
import time
from threading import Thread
import uno
COLUMN_A, COLUMN_B, COLUMN_C = 0, 1, 2
FIRST_ROW = 0
def start_counting_images(action_event=None):
t = Thread(target = keep_counting_images)
t.start()
def keep_counting_images():
oDoc = XSCRIPTCONTEXT.getDocument()
oSheet = oDoc.getSheets().getByIndex(0)
oDrawPage = oSheet.getDrawPage()
messageCell = oSheet.getCellByPosition(COLUMN_C, FIRST_ROW)
messageCell.setString("Starting...")
prevCount = -1
while hasattr(oDoc, 'calculateAll'): # keep going until document is closed
count = oDrawPage.Count
if prevCount == -1 or prevCount != count:
prevCount = count
messageCell.setString("Number of Images: " + str(prevCount))
update_copied_images(oSheet)
time.sleep(1)
def update_copied_images(oSheet):
originCell = oSheet.getCellByPosition(COLUMN_A, FIRST_ROW)
originString = originCell.getString()
messageCell = oSheet.getCellByPosition(COLUMN_B, FIRST_ROW)
if len(originString):
messageCell.setString("originString '" + originString + "'")
else:
messageCell.setString("originString length is zero")
g_exportedScripts = start_counting_images,
To run, go to Tools -> Macros -> Run Macro, find the .py file under My Macros where you put this code, and run start_counting_images.

Autohotkey if statement not working, no error msg

I'm trying to use autohotkey to gather a chuck of data from a website and then click a certain spot on the website depending on what the text is. I'm able to get it to actually pick up the value but when it comes to the if statement it won't seem to process and yields no error message. Here is a quick sample of my code, there is about 20 if statement values so for brevity sake I've only included a few of the values.
GuessesLeft = 20
Errorcount = 0
;triple click and copy text making a variable out of the clipboard
;while (GuessesLeft!=0) part of future while loop
;{ part of future while loop
click 927,349
click 927,349
click 927,349
Send ^c
GetValue = %Clipboard%
if ( GetValue = "Frontal boss")
{
click 955,485
Guessesleft -= 1
}
else if ( GetValue = "Supraorbital Ridge")
{
click 955,571
Guessesleft -= 1
}
;....ETC
else
{
Errorcount += 1
}
;} part of future while loop
Any tips on what I might be doing wrong. Ideally I'd use a case statement but AHK doesn't seem to have them.
Wait a second -- you are triple clicking to highlight a full paragraph and copying that to the clipboard and checking to see if the entirety of the copied portion is the words in the if statement, right? And your words in the copied portion have quotes around them? Probably you will have to trim off any trailing spaces and/or returns:
GetValue = % Trim(Clipboard)
If that doesn't work, you may even have to shorten the length of the copied text by an arbitrary character or two:
GetValue = % SubStr(Clipboard, 1, (StrLen(Clipboard)-2))
Now, if I am wrong, and what you are really looking for is the words from the if statement wherever they may be in a longer paragraph -- and they are not surrounded by quotes, then you will want something like:
IfInString, Clipboard, Frontal boss
Or, if the quotes ARE there,
IfInString, Clipboard, "Frontal boss"
Hth,

Finding cell reference in For loop

I am running a regex text to find invalid data in a range. I want an error message box to display the location of the error when it is found as the data sets are large.
So far my for loop is:
For Each cell In rng1
Dim vntData As Variant
vntData = cell
If Not (regtext.test(vntData) Or cell.value = "") Then
MsgBox "Failed to validate data [" & vntData & "] in cell E" & n & ".", vbExclamation, "Regular Expressions"
cell.Select
Exit For
End If
If n < 100000000 Then
n = n + 1
End If
Next cell
This does the required job. However I would prefer to have a general cell reference (rather than specifying "E") since I need to use it in several different cases.
Is there a way to get the cell reference from the variable "cell" in this case?
Use cell.address. MSDN docs on this method are here, or see the VBA help file within Excel.

OpenOffice.org/LibreOffice Calc macro: is a cell's content currently overflowing?

I have a bunch of cells whose font size I'd like to tweak if their content is overflowing, until it all fits. I'd like to write a macro to do this, unless there's a conditional formatting or other formulaic way of doing it. Is there a property that tells whether a cell is overflowing? If so, what is it?
'open office 3
'get current document
oDoc = ThisComponent
' get first work sheet
oSheet = oDoc.getSheets().getByIndex(0)
'first cell in the work sheet
Cell = oSheet.getCellByPosition(0, 0)
MsgBox Cell.CharHeight
Happy Coading :))