This cell duplicates image in that cell in spreadsheet? - openoffice-calc

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.

Related

Equation in if branch is not executed

I have a question that confused me for a long time. As you know, when we use an if condition in Modelica, that means if the expression is true, then Modelica will do the corresponding equation.
But when i test the following code, I am confused:
model Model134
Real a(start = 0);
equation
if not sample(0, 2) then
a = 1;
else
a = 3;
end if;
end Model134;
I think a will be changed every 2s (start time=0), but when I simulate this model, it dose not change and a is equal to 1 all the time.
Dose anybody know the root cause?
a does change its value, but depending on your simulation tool you might not see it in the plot.
sample(0, 2) creates a time event every 2 seconds. The return value of sample() is only true during the event. So the value of a changes, but after the event it immediately changes back.
In this answer to a similar question, it is mentioned that Dymola stores the value before and after the event in result file. Intermediate values are skipped for efficiency reasons (there can be many for every event, which would bloat up your result file). Hence you can not plot this change in Dymola. For OpenModelica see the answer by
Akhil Nandan.
To proof that a really does change its value you can use this code for example:
model Model134
import Modelica.Utilities.Streams.print;
Real a;
equation
if sample(0, 2) then
a = 1;
else
a = 0;
end if;
when a > 0.5 then
print("a is " + String(a) + " at t=" + String(time) + "s");
end when;
annotation (experiment(StopTime=10));
end Model134;
You should see something like this in the simulation log:
a is 1 at t=2s
a is 1 at t=4s
a is 1 at t=6s
a is 1 at t=8s
a is 1 at t=10s
This is the plot simulated when trying your above code in OpenModelica with settings shown in the second figure.
A time event is triggered when sample(startTime,interval) evaluates true at every multiple of 2 seconds and based on your code logic this should activate else
block and assign value of variable a to be 3.

OpenOffice calc, can macros update cell content automatically?

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.

How to stop printing using if statement with openpyxl

I'm reading values from an excel workbook and I'm trying to stop printing when the value of a specific cell equals a string. Here is my code
import openpyxl
wb = openpyxl.load_workbook('data.xlsx')
for sheet in wb.worksheets:
nrows = sheet.max_row
ncolumns = sheet.max_column
for rowNum in range(20,sheet.max_row):
Sub = sheet.cell(row=rowNum, column=3).value
Unit = sheet.cell(row=rowNum, column=6).value
Concentration = sheet.cell(row=rowNum, column=9).value
com = rowNum[3]
if Sub == "User:":
pass
else:
print(Sub, Concentration, Unit)
The problem is that the if statement doesn't work. When I use type(Sub), python return <type 'unicode'>
Do you have any idea how to do it ?
Thanks
Sounds like you're test is failing. All strings in Excel files are returned as unicode objects but "User:" == u"User:". Maybe the cells you are looking at have some whitespace that isn't visible in your debug statement. In this case it's useful to embed the string in a list when printing it print([Sub])
Alternatively, and this looks to be the case, you are getting confused between Excel's 1-based indexing and Python's zero based indexing. In you code the first cell to be looked at will be C20 (ws.cell(20, 3)) but rowNum[3] is actually D20.
I also recommend you try and avoid using Python's range and the max_column and max_row properties unless you really need them. In your case, ws.get_squared_range() make more sense. Or, in openpyxl 2.4, which allows specify the known edges of a range of cells.
for row in get_squared_range(ws.min_colum, 20, ws.max_column, ws.max_row):
Sub = row[2].value # 3rd item
Unit = row[5].value
Concentration = row[8].value
In openpyxl 2.4 get_squared_range can be replaced:
for row in ws.iter_rows(min_row=20):

How to add regex matches to list in VB.net

I am having a Regex and I want the matches to be added to my previous List. The list (called "Items") has already some entries. (It got the entries from a listbox1 and added is now a datasource of the listbox1)
This is my source:
Dim Items As List(Of String)
<some other code here>
For Each Bam As Match In Treffer
If hashtagz = False Then
ListBox1.Items.Add(Bam.Groups(1).ToString)
ElseIf hashtagz = True And FirstHashtags = True Then
ListBox1.Items.Add(Bam.Groups(1).ToString)
ElseIf hashtagz = True And FirstHashtags = False Then
Items.Add(Bam.Groups(1).ToString)
Console.WriteLine(Bam.Groups(1).ToString)
End If
Next
The last part is important (the last if loop with hashtagz = true and Firsthashtags = False)
I also added the console.writeline to see what is going on. In the console, I get all the new scraped and correct information. In the Items list however, I just get a duplicate of what has been already stored in there instead of adding and updating my list with the new regex matches.
edit Additional information: The whole if condition is in a timer, so it runs again and again. At first it will add entries to a listbox. Then (now important!) it will do the Items.Add(Bam.Groups(1).ToString). It seems to add the new entries the FIRST time THAT part of the code gets executed, but after it is being run trhough again trhough a timer, it will just add the previous entries again and again
Dim Items As New List(Of String)
Dim hashtagz As Boolean
Dim FirstHashtags As Boolean
' Other code here
For Each Bam As Match In Treffer
Select Case True
Case Not hashtagz
ListBox1.Items.Add(Bam.Groups(1).ToString)
Case FirstHashtags
ListBox1.Items.Add(Bam.Groups(1).ToString)
Case Items.Contains(Bam.Groups(1).ToString)
' Already Exists
Case Else
Items.Add(Bam.Groups(1).ToString)
Console.WriteLine(Bam.Groups(1).ToString)
End Select
Next
After using more than 7 hours today (and a few hours yesterday, I am a newbie in VB) of testing, going through my code and building in some outputs to see where the problem is...
My concept is correct, there are no logical errors in the flow of my programm, as one can see from the console.writeline(Bam.Groups(1).ToString . I tested everything and ended up putting in a richtextbox and its like this now
For Each Bam As Match In Treffer
If hashtagz = False Then
ListBox1.Items.Add(Bam.Groups(1).ToString)
ElseIf hashtagz = True And FirstHashtags = True Then
ListBox1.Items.Add(Bam.Groups(1).ToString)
ElseIf hashtagz = True And FirstHashtags = False Then
Items.Add(Bam.Groups(1).ToString)
RichTextBox1.Text = RichTextBox1.Text + Bam.Groups(1).ToString & vbNewLine
End If
Next
The adding procedure seems to be looking correct with the richtextbox, but when I want to add to the Items list, it just gives out the duplicates of the previous entries instead of adding to it. The .add seems to work only the FIRST time running through that line of code, after the second time it just gives out the duplicate of the entries.
I am still trying to figure out WHY that is and I will trying to understand the posts above. Maybe someone else has also an explanation, jsut in case the others were wrong
Edit I have been experimenting still with all this, I have a function that grabs the last entry of my item list and prints out a part of it. When I do that, the print seems correct and updated. So it seems like the list IS actually being updated somehow since the "getting a part of the latest entry of list" is working and always updated. But when I want to show or save the content of the item list, that's when I get the duplicates and the updated and newest entries are not being shown!
Alright guys, I am back again after testing.
The code I posted above was correct. The real reason behind the mistake was in a few other parts of the code, which resulted in partially duplicated output of the entries of the list etc.
I lost track of the variables and the procedures my program was doing. Any hints or tips for me on how to keep track of the code on what it does and having everything in mind or how to properly structure code etc. so that I won't get lost again and again in the code?
This case can be closed, sorry for the inconvenience.

Checkbuttons using dictionary will not update values

Folks,
So I've been working on a little GUI using Tkinter for a capstone project, and given the circumstances, I've only been programming for about two weeks before I was thrown into this, so I'm still a newbie.
My issue today is that I cannot manage to get my checkbutton dictionary to update values; the output for my checkbutton is always 0 or False. The code is as follows:
...
datatype= {'Joint Angle' : 0,
'Joint Acceleration' : 0,
'Ground Reaction Force' : 0,
'Muscle Activation' : 0
}
for measure in datatype:
datatype[measure] = IntVar()
dt_cb = Checkbutton(root, text=measure,
variable=datatype[measure],command = enable_location_state)
dt_cb.grid(column=0, sticky='W', padx=20)
dt1 = datatype['Joint Angle'].get()
dt2 = datatype['Joint Acceleration'].get()
dt3 = datatype['Ground Reaction Force'].get()
dt4 = datatype['Muscle Activation'].get()
...
So I tried periodically printing values throughout the code and I continued to get 0 as soon as I booted the GUI, and after that, no matter what I clicked, the numbers did not update. I read that I should try BooleanVar() and StringVar() instead, but neither of those worked. The code is based off of another bit of code I found somewhere on stackoverflow, though I cannot remember exactly where.
I tried making it a list rather than a dictionary in order to overcome my problem because I was successful with lists previously, but the list created only a single checkbutton for all of those and I was unable to differentiate what is what.
The command enable_location_state configures other checkbuttons, and is as follows:
def enable_location_state():
if dt1 == 1 or dt2 == 1:
ja_cb.configure(state=ACTIVE)
if dt3 == 1:
grf_cb.configure(state=ACTIVE)
if dt4 == 1:
emg_cb.configure(state=ACTIVE)
Your problem is that you are getting the values of the IntVar only once: at the same moment you create your buttons. Move your .get() statements to the beginning of the enable_location_state() function. That way, every time your checkbutton is clicked, the function will check on (i.e., .get()) the value of the IntVar.