Preserve settings in the file - vba

I am creating my excel add-in that saves the current file as csv into user-specified folder. I would like my program to ask for the folder path the first time the program is launched and to remember that folder in the future. I am wondering is there any way to preserve the data within the program? I figured that I could write the path into .txt-file but that feels a little hack-like solution and would clutter the addin folder.

I use the GetSetting and SaveSetting functions in my VB 6 apps. Rather than cover them in detail, take a look at this excellent web page that illustrates how to use in with Excel
Excel Tips From John Walkenbach

Create a Worksheet, and store the values in cells. Then in the VBA Editor find the Worksheet in the Project Explorer (Ctrl + R) and set "Visible" to "2 - xlSheetVeryHidden" in the Properties Pane (F4) so that it is not readily visible to users.
You can then set/retrieve the data in with code in the format SheetName.Cells(row,column).Value, e.g.
MyPath = Sheet1.Cells(1,2).Value 'Get data from cell B1
Sheet1.Cells(2,2).Value = NewPath 'Set data in cell B2

There are multiple ways to approach this. Besides the hidden sheet approach, already described, you can
Write the information to a CustomXMLPart. This is a xml file stored in the workbook's ZIP file where information can be stored.
For something as short and simple as a file path, you could also use a CustomDocumentProperty

Related

VBA loop through non-patterned files in folder (seek for opinions) [EDIT]

I am here for seeking any advice or opinion as I want to loop through every excel files in folder. As you can see from my attached picture, my excel files are different both in file types (.xls <> .xlsx) and filename (especially on 2018). I also need to loop through "Revised" or "revised" files as well since it is possibly that any file will be revised next time.
And yes, I also did some research on this. My understanding is I need to modify all of the file names into the pattern one before build up a VBA to loop. At first, I thought about decomposing all filenames and put it back in pattern form, but it sound too idealistic. Another way is using the date in each file to label the workbook name, but again I found that those date had different styles. Some files label the date by using string such as "January 2012" or "March 2014", while the others using the date form such as "19/08/2013".
Therefore, I would be appreciated if anyone could suggest me on;
How can I handle with the different file name (.xls and .xlsx) within the same VBA?
How should I deal with these different file names (some files have "revised" at the back; some do not have "-" between "Cons" and date; and some use month name instead of number)? Are they any pattern that I overlook?
Please noted that I am just a newbie VBA coder, so it would be great if you left your answers with an explanation or any kind of examples.
Many thanks.
--------------------------------------------------------[EDIT]-------------------------------------------------------------------
First of all sorry for my poor explanation before. I provided too few information to understand overall picture. Let's start this over again.
My data are about steel consumption which release from the authority
every month. My task is to gather all of these data (such as
production, import, export and consumption of every data in each
row) and generate into time series pattern (please see attached
excel screen)
As it is possibly that these data will be revised anytime, I thus
decide to download all of these file every time in every month (one
file per one month). In addition to those revised file, the
authority will unexpectedly rename those file for example, from
"Cons 201601.xlsx" into "Cons 201601 - revised.xlsx)". This make me
more difficult to work on this (please see attached folder for
reference).
Moreover, this authority seems to have a problem with file naming as
they had different pattern of filename in the past compare to the
present ones. Example is per below table; Cons 201701-Revised.xlsx
Cons 201710-Revised1.xlsx
Cons 201711.xlsx
Cons-200902.xls
Cons-201212_revise.xls
Cons-201401-revised.xls
I mention above file name in order to create a VBA to loop through
these file, select some content and paste into another workbook in
chronological order. This means that I cannot use "Loop while or Do
while function" in my VBA. At first I decided to use two integer
variables, both of which were set for years and months
(e.g. For i = 2009 to 2018 and For j = 1 to 12) in order to created the system of filename (such as filename = "Cons" & "-" & i & j). But,
as I stated before, non-patterned name by the authority had
prevented me from creating this kind of loop.
I also tried to use the date in cell B2 in figure 1 to label the
date in order to create the loop which I already explained before.
However, again, the authority did not use the same pattern to date
month and year. After I checked with many file, these are example of
the date style in cell B2 January 2012 (string)
February 2009 (string)
Jan-16 (1/1/2016 date in custom format)
Given above limitations, could you guys again suggest me any possible
way to create chronological loop so as to copy and paste data to another
workbook to form a set of time series data for each product?
Thank you for your kind help :)
Firstly, use FileSystemObject (include a reference to Microsoft Scripting Runtime in your VBA project) which has some helpful functions within it. You could always code your own, but why reinvent the wheel in this case?
Don't have time to codes something this morning, so here is the pseudocode:
Open a Folder using your known filepath
Loop through all the files in the Folder (For each f in Folder.Files
extract the date code from your filename (e.g. using RegEx)
Add to a collection (e.g. array or Dictionary item) of the filename and the extracted date code (your key).
(end loop)
Sort your collection based on the extracted date code
This now gives you an ordered list of files, which you can open in turn and extract the data. An added bonus is that the key in the collection gives you a consistent date representation which you can use as an index in your collated information.
If you just want to loop through all files in folder use this:
dim file as variant
file = Dir("<PathToFolder>")
While (file <> "")
'Your logic here
file = Dir
wend

Change Path to Picture Links in Excel

I have manually pasted a large number of linked pictures into a 2010 Excel spreadsheet using insert picture -> select picture location --> link to file. These pictures are part of a report. I update the pictures using R each quarter, and my report automatically updates. Perfect.
I now need to change the directory where the plots are kept, and need to update the links. As there are around 200 of them (its a big report), I want to do this in VBA. Whilst I can loop through the pictures ok (ActiveSheet.Pictures), I can't seem to find the links/address. Any idea how I can see the underlying file location so I might change it - the reference has to be stored somewhere (note - these don't seem to be stored as hyperlinks).
Any idea how I can see the underlying file location so I might change it - the reference has to be stored somewhere
Create a new folder
Paste a copy of the .xlsx or .xlsm excel file
Uncompress the file with a zip tool (i'm using 7-Zip)
Delete the .xlsx or .xlsm file (optional)
Now we have all the component parts of the original file as plain text xml files and folders
Inside the folder xl\drawings\ _rels there are files named as drawing2.xml.rels, drawing3.xml.rels, ...
It seems that each file corresponds to a sheet and stores the paths to images in this format:
Target="file:///C:\Users\myusername\Documents\MyImageFolder\My%20Image%20Name.png"
Change the paths with a text editor
Compress all the contents of the folder to a .zip
Change the extension to the original .xlsx or .xlsm
These steps could be automated with VBA, AutoIt, etc., here some references:
An example with AutoIt and 7-zip
http://www.jkp-ads.com/Articles/Excel2007FileFormat.asp
http://www.jkp-ads.com/Articles/Excel2007FileFormat02.asp
Ron de Bruin zip examples with VBA
Read and change multiple XML files in Excel (2007) VBA
Excel uses the Formula Bar as the link in this case, just the same as it would link between ranges in two different worksheets. When I select a linked picture, the formula below populates in the formula bar:
=[TrialWB.xlsm]Sheet1!$C$3:$E$6
You can access the Shape's formula using the code below and inserting your picture's specific name:
ActiveSheet.Pictures("Picture Name").Formula = "=[TrialWB.xlsm]Sheet1!$C$4:$E$6"
In updating the links, you'll have to change the file path in the formula. This might look like:
ActiveSheet.Pictures("Picture Name").Formula = "='C:\Reports2015\[TrialWB.xlsm]Sheet1'!$C$4:$E$6"
changing to
ActiveSheet.Pictures("Picture Name").Formula = "='C:\Reports2016\[TrialWB.xlsm]Sheet1'!$C$4:$E$6"
This question may be of some further assistance for accessing formulas:
Excel: create image from cell range
And here's a useful Microsoft page for formula file path editing: https://support.office.com/en-us/article/Create-an-external-reference-link-to-a-cell-range-in-another-workbook-c98d1803-dd75-4668-ac6a-d7cca2a9b95f

Copy tabs/sheets from one workbook to another with macro/vba code (1 button)

two (hopefully) easy questions -
Can I copy 2 tabs from File1.xlsm to a master.XLSX file and still run the macro code? I assume not?
Assuming I cannot do #1, can I copy the 2 tabs into another master.xlsm file? If so, please help I've tried the following.
File1.xlsm just has a grid with a 1 button that calls 'File1.xlsm'!getData which populates the grid.
I was able to right click the tabs in File1.xlsm and move/copy them successfully into master.xlsm but without the vba getData Sub(). When I click the button it said it couldn't find the !getData code. Is there a clean way to copy the 2 tabs, and !getData macro code into the Master.xlsm?
Thanks a bunch in advance!
To accomplish this task, you should consider adding the relevant code into a module within your File1 workbook. You will need to enable the Visual Basic extensibility within your File1 workbook library.
You would then need to copy the module along with the two sheets into the new workbook. You would do this with commands similar to the following.
ActiveWorkbook.VBProject.VBComponents("module1").Export Path
SomeWorkbook.VBE.VBProject.VBComponents.Import Path
Where path is a string variable to a place where you would like to place the module, and someworkbook would be your Master.xlsm workbook object.
with ActiveWorkbook.VBProject
.VBComponents("sheet1").codemodule.addfromstring .VBComponents("Sheet1").codemodule.lines(1,.VBComponents("Module1").codemodule.CountofLines)
end with
sheets(array("sheet1","sheet2")).copy

In batch file, how to get focus on a specific window (opened file)

A very simple question I suppose, but I reached a deadlock with this:
I have to use a .bat file to imput plain text data into the right cells an excel sheet with lots of graphics content, vba parts, macro that deactivate "normal" EXCEL buttons and functions, password to protect the pre-typed functions, sudden and unexpected changes in the version of the "taget file", and many other complications...
My need is to be absolutely sure that the .bat is sending the sequence into the right version of the .xlsm file.
To do that I want to store the last known filename (that include the file version) in the .bat file, and I want to take focus on the excel window in wich the data have to be written ONLY IF the title of the excel window is exactly the same.
So Here is the question: How to get the focus on a specific open file from a .bat file?
You can't. If you wanted to use vbscript or jscript you could do what you want in a command prompt in an unreliable way (but it will work most circumstances).
Excel has it's own forms.
Put column headers in a row. Put selection in same row. Alt + D, O.
Plus you can make Excel only allow entries on some cells, like a invoice form.
Right click cell, Properties, Protection, Unlock. Then Alt + T, P, P.
Word has it's own forms similar to Excel (Word is also a spreadsheet).
Excel VBA language (and VBScript too) has input box command.
Sub main()
Sheet1.Range("A1").Value2 = InputBox("enter Value")
End Sub

Update hyperlinks in shapes when file location changes

I have a process flow diagram that uses various excel shapes to visually represent a data production process from start to finish, I.e. from data input to analytic environment to data output to submission file. I have used vba to hyperlink many of the shapes in the diagram to another sheet in the workbook (using thisworkbook.fullname) that contains definitions for abbreviations contained in the text of each shape, eg C1 is listed in a shape, the hyperlink takes you to the definition tab cell where C1 is defined as control point one. The hyperlinks work when the xlsm workbook is in my home location where i saved the file but they do not work if I save the file to another location (they try to open my original workbook). Is it as easy as changing the hyperlink addresses to thisworkbook.filename and dropping the path to make this work? do i need to create a macro that will automatically look up the old hyperlink address and replace it with the new address of current file location for every shape in the workbook containing a hyperlink. The path could change in the future, so want it to be relative and not fixed - for example if I save the file to share point and another user saves a copy to their home directory, I still want the links to work for them in either location. Some hyperlinks go to "sheet1" some to "sheet2" for example, but sheets 1 & 2 are both located in the same workbook. Please help!
ActiveWorkbook.Name solves the problem, replace ThisWorkbook.FullName with it and hyperlink works in other directories.