I am trying to create a VB script that searches through a column of dates and returns the address of the cell with todays date.
For some reason I keep getting an "Object required: 'FoundCell'" error.
Could someone have a look at my code and correct me?
I can read out the date using WScript.Echo, but once I use it in the find function it immediately gives me the error.
Set oExcel = CreateObject("Excel.Application")
Set wshShell = CreateObject("Wscript.Shell")
File_Path = "D:\Work\Personal Timemanagement\test.xlsx"
Set oData = oExcel.Workbooks.Open(File_Path)
WHAT_TO_FIND = Date()
WScript.Echo WHAT_TO_FIND
Set FoundCell = oData.Worksheets("tst2").Range("A1:A40").Find(WHAT_TO_FIND)
oExcel.Cells(4,4) = FoundCell.Address
oExcel.ActiveWorkbook.SaveAs "D:\Work\Personal Timemanagement\test2.xlsx"
oExcel.ActiveWorkbook.Close
oExcel.Application.Quit
WScript.Quit
Thanks for the help!
WHAT_TO_FIND1 returns value like #14/10/2014#.So replace the # with nothing using WHAT_TO_FIND1=Replace(WHAT_TO_FIND,"#","Nothing").
Once replaced the above code will work
I tried your script, works perfect for me.
For testing purposes I suggest you add the following line to the script
oExcel.Visible = True
Also make sure all the privies instances of Excel are closed so your script could get write access. (open task manager and end all Excel process - unless you have other excel files open)
Now make sure the Worksheet is spelled correct "tst2" also ensure that the range is correct "A1:A40"
Keep us posted.
Find() returns Nothing when the given value isn't found in the given range. Make sure that the Range A1:A40 on sheet tst2 in the workbook D:\Work\Personal Timemanagement\test.xlsx actually contains a cell with the current date, and that the cell is also formatted as a date. Find() won't return a match if for instance you're looking for a date 7/11/2013 and the range contains a cell (formatted as text) with the string 7/11/2013. Modify your statement like this for finding "text" cells:
Set FoundCell = oData.Worksheets("tst2").Range("A1:A40").Find(CStr(WHAT_TO_FIND))
Related
Using VBA, how do you find the name of the range of an active cell (merged cells)? I have a worksheet that I have established a few named ranges. i.e. K7:R28 is a range of merged cells and is named "LocM11". I typed that into the Name box and it is already established. In my VBA code, if a user clicks on the merged cells of K7:R28 and presses a command button I want the code to return the name "LocM11" and save it as a variable to be used later in the code. I've looked everywhere but this has me stumped. Any advice is appreciated.
I've tried some code sniplets I found on the internet to no avail. I've found code that uses VBA to name a range, but I do not want to do that. I have the name established. I want to know the already existing Name and save it as a variable.
try this
Dim activeRange As Range
Dim rangeName As String
Set activeRange = ActiveCell.Range
rangeName = Application.Range(activeRange.Address).Name
Debug.Print rangeName
More details - https://learn.microsoft.com/en-us/office/vba/api/excel.application.range#example
I've got a dataflow with a csv file as source. The column NewPositive is a string and it contains numbers formatted in European style with a dot as thousand seperator e.g 1.019 meaning 1019
If I use the function toInteger to convert my NewPositive column to an int via toInteger(NewPositive,'#.###','de'), I only get the thousand cipher e.g 1 for 1.019 and not the rest. Why? For testing I tried creating a constant column: toInteger('1.019','#.###','de') and it gives 1019 as expected. So why does the function not work for my column? The column is trimmed and if I compare the first value with equality function: equals('1.019',NewPositive) returns true.
Please note: I know it's very easy to create a workaround by toInteger(replace(NewPositive,'.','')), but I want to learn how to use the toInteger function with the locale and format parameters.
Here is sample data:
Dato;NewPositive
2021-08-20;1.234
2021-08-21;1.789
I was able to repro this and probably looks to be a bug to me . I have reported this to the ADF team , will let you know once I hear back from them . You already have a work around please go ahead that to unblock yourself .
The title says it all...
For example, if I want to have a cell which displays the current time and auto updates minute by minute (well, I think we call that a clock), how do I do it?
Is there a simple function implemented already or should I create a macro and assign it to a specific event?
EDIT: Following the provided answer by #Jim K, I want to be more clear about what I want. The "clock" example above was here to make it simple to understand, but what I really want is in the title: a cell value which changes periodically, be it a string, a number, a date...
First enter =NOW() in a cell, and format the number by going to Format -> Cells.
Next, this Basic macro (from here) recalculates every minute. Go to Tools -> Customize and assign it to the Open Document event.
Sub RecalculatePeriodically
Const secs = 60
On Error Goto ErrorHandler
Do While True
Wait(1000 * secs)
ThisComponent.calculateAll()
Loop
ErrorHandler:
'Document was probably closed
End Sub
However, this crashes when exiting LibreOffice. So instead, use the following threaded Python macro (like here). Assign keep_recalculating_thread to the Open Document event.
import time
from threading import Thread
import uno
def keep_recalculating_thread(action_event=None):
t = Thread(target = keep_recalculating)
t.start()
def keep_recalculating():
oDoc = XSCRIPTCONTEXT.getDocument()
while hasattr(oDoc, 'calculateAll'):
oDoc.calculateAll()
time.sleep(60)
g_exportedScripts = keep_recalculating_thread,
Another idea is at https://ask.libreoffice.org/en/question/5327/how-can-i-run-a-macro-at-regular-time-interval/, although it requires linking to another file which seems cumbersome.
EDIT:
Maybe you are looking for something like this? Test it by starting with a blank spreadsheet and entering 1 in cell A1.
def keep_changing_cell(action_event=None):
t = Thread(target = keep_changing_thread)
t.start()
def keep_changing_thread():
oDoc = XSCRIPTCONTEXT.getDocument()
oSheet = oDoc.CurrentController.ActiveSheet
COLUMN_A = 0
FIRST_ROW = 0
oCell = oSheet.getCellByPosition(COLUMN_A, FIRST_ROW)
while hasattr(oDoc, 'calculateAll'):
oCell.setValue(oCell.getValue() + 1)
time.sleep(2)
tl;dr
Is there a simple function implemented already
No.
From LibreOffice and fairly recent:
(I don't know a 'clock' property applying to cells.)
There are simple ways to obtain the time, for example given suitable formatting, with date:
=NOW()
or Ctrl+;
Or, for example, without date:
=MOD(NOW(),1)
The first and last will update, but only when the sheet is recalculated.
For a cell that ticks away (eg second by second) I believe you will need a script.
I'm trying to convert a Word VBA procedure to an AppleScript and only having partial luck.
Here's the first version of the VBA procedure:
Public Sub postprocessMerges1()
Dim rng As Range
Selection.HomeKey unit:=wdStory
With Selection.Find
.ClearFormatting
.Forward = True
.Wrap = wdFindStop
.Format = False
Do
.Text = "..."
.Execute
If .Found Then
.Parent.Select
Set rng = Selection.Range
rng.MoveStart unit:=wdParagraph, Count:=-1
rng.MoveEndUntil cset:=Chr(13)
rng.Text = formatAmounts(rng.Text)
End If
Loop While .Found
End With
End Sub
And here's my corresponding AppleScript:
on postprocessMerges()
tell application "Microsoft Word"
home key selection move unit a story extend by moving
set selFind to find object of selection
clear formatting selFind
set foundIt to true
repeat while foundIt
set foundIt to execute find selFind find text "..." wrap find stop with match forward without find format
if foundIt then
set foundRng to text object of selection
set foundRng to move start of range foundRng by a paragraph item count -1
set foundRng to move range end until foundRng characters {return}
set tt to (content of foundRng)
set (content of foundRng) to my formatAmounts(tt)
end if
end repeat
end tell
end postprocessMerges
Okay, so that works just fine. However, I'd like it to be better. The way the script is currently written, it actually jumps from hit to hit, highlighting the found text and performing the replacement generated by the formatAmounts subroutine. Not bad, but when you're working with a 200+ page document, it gets a little tedious to see that happening onscreen.
So in VBA, I can do this:
Public Sub postprocessMerges2()
With ActiveDocument.Content.Find
.ClearFormatting
.Forward = True
.Wrap = wdFindStop
.Format = False
Do
.Text = "..."
.Execute
If .Found Then
With .Parent
.MoveStart unit:=wdParagraph, Count:=-1
.MoveEndUntil cset:=Chr(13)
.Text = formatAmounts(.Text)
.Collapse direction:=wdCollapseEnd
End With
End If
Loop While .Found
End With
End Sub
This will perform the exact same action as the first procedure, but it does so on the document's content range rather than the selection range and so I don't have to watch Word jump around from page to page to page. Much more preferable, but not something I've been able to emulate in AS.
Specifically, I can't seem to get the hit range each time through the loop without selecting it first. The find object in Word's AS dictionary doesn't have a Parent property I can access like I do in VBA.
Is there anything I'm missing? Is what I do in the second VBA proc actually replicable in AS?
This is using Word 2011 and AppleScript 2.3 on OS X 10.9.3.
This should probably be a comment, but...
Is what I do in the second VBA proc actually replicable in AS?
Let me put it this way. I think you will probably end up using the Selection object a lot more in AS than you are probably used to doing in VBA. In this case, in VBA, the Find.Execute should return a new Range, but in AS it just returns true/false. If you look it up in the AS dictionary, it looks as if the execute find should return a "text range/insertion point" but what it actually returns is what is stated in the description at the top of the entry for "execute find", i.e. a boolean. The find object does not have a range. So it is difficult to see how to get the range of the thing you just found. As far as I can tell, using execute find in AS with a find object derived from a range object is only useful in the situation where you can specify the replacment object and do the entire replace in the execute.
It might also be useful to read Matt Neuberg's comments in this conversation
I am grabbing a .txt file and trying to reverse it, but I get this error when I try to, I don't understand it. Help please?
array_reverse() expects parameter 1 to
be array, string given in ......
Here is the code:
$dirCont = file_get_contents($dir, NULL, NULL, $sPoint, 10240000);
$invertedLines = array_reverse($dirCont);
echo $invertedLines;
A string is not an array? Even if it were (as in C strings) it would not work as you expected. You'll need to split the file on line breaks (if you're trying to reverse to get the end of the file first).
$invertedLines = array_reverse(preg_split("/\n/", $dirCont));
I think you need to pass the value on an array.
array_reverse(array($dircont));
This is working fine for me.