I'm trying to make a macro that, among other things, updates external file links in several cells, where the file location currently in the cells and that which I want to change it to are specified by the user in another tab.
I've tried to do this via find/replace; if I try to do this with the text specified in the code:
Range("b3").Formula = Replace(Range("B3").Formula, "\\folder\file", "\\folder\newfile")
Then it'll replace this text and the links update correctly. If I change the locations with inputs, say oldlocation and newlocation:
oldlocation= "\\folder\file"
newlocation= "\\folder\newfile"
Range("b3").Formula = Replace(Range("B3").Formula, oldlocation, newlocation)
This also works ok. But if I change the definitions of the locations (e.g. B3: "\folder\file"):
oldlocation= Range("b3").text
newlocation= Range("b4").text
It no longer works - passes over the line in the code with no change or error. I've made a quick check and Range("b3").text & "\folder\file" both seem to be text strings; after that I'm stumped. I've tried a few different find/replace formats I've found, but all with the same result. What am I missing?
The problem is when you define the string to be replaced as
oldlocation= Range("b3").text
the oldlocation variable will have the value of the cell (the data you see in the cell) not the formula of the cell that contains the current reference, so the replace function does not find the string to be replaced.
You have to extract the location that you want to replace from the Range("b3").formula string and work with that.
Related
I am helping to update someone else's VBA code since they got pulled to a different project. The code reads data from an input sheet, then unhides 4 results forms, populates them, saves them as a CSV file, then rehides them.
The issue: One of the data entries are numbers formatted as ##-#, like 20-2, 13-5, and 12-1. The 12-1 is the issue. Excel sees it and reads it as a date format and prints 1-Dec in my results sheet.
Solutions I've tried: I tried stopping the program before it rehides the data and changing the format but it throws off the numbers. And then I can't save it either, because the program has run halfway and I don't want to save the document like that. I then tried to unhide the sheets at the end after the program ran and cleared, but without completely removing the data after the program runs, it doesn't run correctly when you try to run it a second time. Lastly I tried unhiding before the program even ran and changed the format setting from "General" to "Text", but even after saving and closing it doesn't seem like that had an affect.
My Question: First of all am I changing the format right? And secondly does anyone know how to combat excel automatically formatting in this way. I have been working in VBA for about 3 weeks and have only encountered this once before but it fixed easily. This one doesn't seem to follow that pattern.
Since I was given an answer I thought I'd run my first self Q & A now, for those who may come upon this in the future. Credit to those users in the comments above for helping me figure this out. A code line like this:
Dim variable1 As Variant
variable1 = Sheets("Sheet 1").Range("A1").Value
Sheets("Sheet 2").Range("A1").NumberFormat = "#"
Sheets("Sheet 2").Range("A1") = variable1
Or with the cells option, we'd see code like this:
Dim variable1 As Variant
variable1 = Sheets("Sheet 1").Cells(1,1).Value
Sheets("Sheet 2").Cells(1,1).NumberFormat = "#"
Sheets("Sheet 2").Cells(1,1) = variable1
Both of these codes dimension a variable to store cell A1 in from Sheet 1, refer to sheet 2 and set that cell to a new format (making it format as a number as opposed to automatically formatting), then the last line sets that newly formatted cell equal to the value in the variable, but while retaining the new format we've set.
I am trying to use one of the excel hidden field for the purpose of referencing. Basically column(A:A) is hidden and it contains specific IDs that I can use it to reference it to another sheet.
I could have moved the column (A:A) further away so that the user does not see it, but my issue is that I have written too many lines of code already. I guess it is poorly constructed, because if I were to move any of my columns, my entire program would definitely break. I could try to fix it, but that would mean I would have to over analyze my own code and I either wouldn't understand it or wouldn't find my mistake.
So, anyways, I have a Range.Find function, which is looking in the hidden field, but returns nothing. I could try to unhide it, and hide it again, but I want to know that if there is a solution in Excel, then to not ignore the hidden field.
Set myCell = Columns(1).Find("search_string", lookat:=xlWhole, LookIn:=xlFormulas)
Debug.Print myCell.Row
Replace "search_string" to the ID you are looking for.
I have an excel file with cells that retrieve data from a file stored on another computer. I need to update the file path in all of these formulas but it is extremely tedious as each time I update the formula, an open file window comes up. The location that I am changing this to is also not on my computer.
Is there a quick way to update a file path formula without having this dialog window open up?
I need to change my path from
='\\clusfs001nas\
To:
='R:\
Under the "Data" Tab, click "Edit Links" - this should show you the files you have linked to, and you can "Change Source" to update it. Alternatively, you could do a simple Find/Replace (CTRL+F, then click "replace" and type the path you need to replace and then in the replace area, put the new path).
You can change formulas using VBA.
But first, I suggest you have it in only one cell, and in the formulas, you add this cell, not a real path. This way, next time you need to change it, you change only one cell.
Now the coding, an example to change A2 and B5:
Sub Change()
Range("A2").Formula = type the formula here between quotes
Range("B5").Formula = type the formula here between quotes
end sub
If you have lots of cells in a column, you could do a loop:
For i = 1 to 20 'say you have cells from row 1 to 20
Cells(i,3).Formula = type the formula here between quotes
'the number 3 above is the third column: C
next
This is late, but one option that can avoid the annoying dialog when you click Replace All is to insert some random characters at the beginning of the path which will prevent Excel from thinking that the string is an actual link. Then you should be able to edit the portions of that path that need to be changed, and once that is complete, do another Replace ALL, basically removing the random characters that were inserted.
You need to be careful of course, because if you choose a random character that happens to be within other formulas the Replace ALL may have some unexpected results
You can write on your code:
Application.DisplayAlerts = False
Application.AskToUpdate = False
I am working with a large Excel file, where I have defined around 2000 names for cells. In addition the excel contains formulas, these formulas are already entered with references to cells (A23-B24). I want to change the cells references by the defined names (instead of A23-B24 having VARIABLE_100-VARIABLE_120).
I know this is possible by selecting "Apply names" and then select the defined names from the list. Because I have around 2000 defined names, I would like to select all the names at once from the menu, but I cannot find an option, so I have to select one by one. I have been looking if there was an option for enabling the multiple selection on the menu, but I have not found such an option.
A work around for me would be to create a macro that applies to the selected range of formulas the selected names. Something like this:
Sub Macro1()
' Macro1 Macro
Selection.ApplyNames Names:=Array ("ATL_BV_XP", "ATL_BV_XP..EUN", "ATL_PK_XP", _
"ATL_PK_XP..EUN", "CHN_PK_IM", "CHN_PK_IM..EUN", "CHN_PK_IM..SHREUN", _
"E15_AG_AH", "E15_AG_EPA", "E15_AG_SFP", "E15_AG_SFP..CF" _
, "E15_APF_FE"), IgnoreRelativeAbsolute:=True, UseRowColumnNames:=True, _
OmitColumn:=True, OmitRow:=True, Order:=1, AppendLast:=False
End Sub
My problem is that because I have a large number of defined names (already wrote like twice that around 2000), listing all names in the macro code becomes really complex. I thought that probably a workaround would be to create a list including all defined names within the code. Does someone has an idea how to do this? I have looking around and some codes suggest a loop while other say it is possible to extract a list. Nonetheless I have not been able to find a way to do it.
The documentation at msdn.microsoft.com says
Names: An array of the names to be applied. If this argument is omitted, all names on the sheet are applied to the range.
see https://msdn.microsoft.com/en-us/library/office/ff196578(v=office.15).aspx
Following on that try this:
Selection.ApplyNames _
IgnoreRelativeAbsolute:=True, UseRowColumnNames:=True, _
OmitColumn:=True, OmitRow:=True, Order:=1, AppendLast:=False
This should work depending on the Scope of the Defined Names and their visibility. Try that and let us know the results.
It may already be available to you. Say we have defined the Names Cost, Profit, Tax
When typing a formula, have the Formula Tab open and you can always pull-down those names:
A macro would be nice, but I don't know how to invoke a macro in the middle of editing.
I'm a beginner in lua (at best).
I have a *.lua script that at some point has a function that when called sets a set of variables. (or updates them)
These specific variables should be extracted from a xls or csv file - something that can be managed by excel.
So in excel I have rows and columns like this:
valuefield_1 100 20 30
valuefield_2 60 150 40
valuefield_3 80 90 170
etc.
I want to be able to search for a specific valuefield through lua in xls/csv, for example "valuefield_1" and get the value in the third third column, which would be 20. This is then saved as variable x in my lua script so that whenever I call variable x, it uses the value 20 until I update variable x with a different value by searching for a different valuefield value.
In my efforts to find a solution to this (seemingly simply) issue, all I came across are xls modules for lua, how to output files, how to do graphs, complicated stuff far beyond what I want to do.
Isn't there a simple way that I can have a line where it defines my variable by saying:
variable_x = value of the cell in the third column in the row of valuefield_x
so that I can simply set valuefield_x in my luascript according to what sort of valuefield I look for?
That's really all I need, I don't need to write xls/csv files or change anything in them. All I want is to accurately read specific cells in specific columns that are chosen by what "valuefield" I search for in the first column.
Can somebody tell me what the commands for that are?
I am not aware of a .xls file reader in Lua and in doubt writing one in pure Lua is feasible (although look at xlrd module in Python, might be easy to convert to Lua). In Python you can do that easily with win32com module so if you have option of using Python instead it is very easy to learn.
For .CSV file you would use open and read just as any other text file then parse with Lua pattern matching. If you post some where you show what you have tried (that's probably why you got so many downvotes) with these then I can post more specific answer.
Thanks for the answer, Schollii.
The problem was pretty much that I didn't even know how to begin with accessing, opening, editing or otherwise using Excel through lua, so any code example was pretty much useless. Thus I thought it best to describe what I required, rather than misdirecting with code snippets that dealt with entirely different things. (such as io.open and other things)
As always, after much - MUCH - research and browsing through 3 different manuals and rereading who knows how many irrelevant answers I came upon an answer that works for me. It's actually very simple, so I cannot begin to imagine how many people could've spared me the hours and hours of research with a five minutes answer. Let's hope that by providing a very thorough answer, I can ensure that other beginner like me who wish to do the same don't have to do the same amount of research. And yes, the answer is very basic, and yes, I'm also explaining things most people who know lua code don't need explained. This is for beginners like me.
First: Download "Lua for Windows"
http://code.google.com/p/luaforwindows/
Lua cannot - by itself - handle excel format, so instead you need to use the plugin LUACOM which is one of the modules installed through "Lua for Windows"
It also includes a nifty script editor whith which you can right-click your scriptfile, click edit script, and you have a nice interface to edit and TEST your script.
The actual script:
The first part of your script requires you to utilize Excel through luacom.
require('luacom')
excel = luacom.CreateObject("Excel.Application")
excel.Visible = true
a.The "require" line tells lua that it requires the module "luacom", to use the modules function for this lua script.
b. The second line through luacom opens an instance of Excel which is in the script referred to as "excel". This is necessary be able to target it with commands.
c. excel.Visible determines whether the open instance of excel can be seen by the user or whether its used invisible. Note how the "excel." reference points at the instance we called "excel" in line 2.
(Alternative)
It's also possible to target an existing instance of excel that has already been opened manually by the user by replacing the second line with:
excel = luacom.GetObject("Excel.Application")
If we use the alternative way, and target an already open excel program, we can already target all the values in the first sheet. If we however create a new instance of excel, we have to open the file we wish to read from.
fpath = "C:\\Examplepath\\Example.xlsx"
wb = excel.Workbooks:Open(fpath)
ws = wb.Worksheets("ImportantSheet1")
a. In the first line of this part, fpath determines the location of the xlsx file we wish to access. Note that "\" are used instead of "\".
b. We create the reference "wb" similar to the "excel reference in our first part of code. This one however opens a Workbook file (your excel file) at the location (fapth). Again, note how "excel." points the code at the excel instance we created earlier.
c. This line determines which sheet is to be opened in the just opened Workbook file. In this case, it's the sheet called "ImportantSheet1".
desired_name = "whatIseek"
for row=1, 4 do
for col=1, 4 do
local cell_location = excel.Cells(row, col).Value2
if cell_location == desired_name then
Value1 = excel.Cells(row, col +1).Value2
Value2 = excel.Cells(row, col +2).Value2
Value3 = excel.Cells(row, col +3).Value2
end
end
end
print(Value1)
print(Value2)
print(Value3)
a. desired_name sets up the value that we seek (in this case a string)
b. Line 2 and 3 determine that the following process is to be done for rows 1-4 and columns 1-4, though you don't have to call those "row" or "col".
c. The next line sets the value of the variable "current cell" to the value of the cell in excel at the position (x, y). You need to use ".Value2" (not ".Value") to in this command. So now our temporary variable has the cells value.
d. In the "if" command, we check if the current value of the cell is equal to the value we specified earlier as the "desired_name" which we seek.
e. If that is the case, "then" the next 3 lines set the Values 1-3 to the cells in the next columns in the same row. (So it "reads" from left to right the next values and saves them as our variable)
f. Finally, to check whether we actually have the values we want, we use the print command to view them when we execute the script. (This is, of course, not necessary to work with those values, this is merely here to check if this script works)