I have found plenty of vba for inserting images into a comment
Selection.ShapeRange.Fill.UserPicture "C:\Temp\Pictures\ewe.jpg"
How can you determine the image already used for an comment?
I would like to extract the embedded image names if possible.
Is there not a property to access that will give me this?
In the comment Fill Effects dialog box the image name somehow seems to be accessible.
Sorry, I didn't have the reputation to just comment on your question for clarification.
I made a test file, inserted a comment and image in that comment, and then extracted the base files. I then checked them all for the original file name. I also found the embedded JPEG and decoded it to get the metadata. As you've noted, the original file names are stored in xl\drawings\vmlDrawing1.vml (once you've extracted the xml files from the excel file by appending .zip to the filename and then running an unzip utility on it). I did find the file name, but not the path or file type, so I'm fairly certain that the path and file type aren't preserved.
If just the file name is sufficient for you, then that file contains information for each drawing that you have, and those will include the cell location, although they're 0 based, so you'd have to add one to get the actual row and column. My question is two part:
1) Is the file name alone sufficient, or did you need the entire path? If you needed the entire path, I think you're out of luck, since the paths are on a different computer and you can't even search for them if you do extract the file name.
2) If that is all you need, does the solution have to be VBA? In the past, I have programmatically unzipped and manipulated the xml base files, but it's a little tricky. It's simplified by the fact that you only have to read out the data, so that's a plus. I did it in .net before, but I'm sure that if it had to be VBA it could be done, but it would be simpler if you were open to the type of solution.
Let me know, I'd be happy to help you out.
====================================================================================
Try this: make a copy of the spreadsheet, append .zip (test.xlsm.zip), and then extract the files manually. Change vmlPath to the location of your xl\drawings\vmlDrawing1.vml file. Then run this. I did make some assumptions, for instance, I assumed that the order of the nodes and attributes would always be the same and so I used hardcoded indexes (shp.attributes(0), etc) instead of using logic to make sure I had the correct node or attribute, but you seem like you know your way around VBA, so I'm just going to code a barebones. This will need a reference to Microsoft XML 6.0.
Sub vmlParse()
Dim vmlPath As String: vmlPath = "C:\Users\Lenovo\Desktop\test - Copy.xlsm\xl\drawings\vmlDrawing1.vml"
Dim this As Worksheet: Set this = ActiveSheet
Dim doc As New DOMDocument, shps As IXMLDOMNodeList
Dim shp As IXMLDOMNode, n As IXMLDOMNode, a As IXMLDOMAttribute
Dim fileName As String, productID As String
Dim rng As Range, r As Long, c As Long
doc.Load vmlPath
Set shps = doc.getElementsByTagName("x:ClientData")
For Each shp In shps
If shp.Attributes(0).nodeValue = "Note" Then
r = 0: c = 0
For Each a In shp.ParentNode.FirstChild.Attributes
If a.nodeName = "o:title" Then
fileName = a.nodeValue
Exit For
End If
Next
For Each n In shp.childNodes
If n.nodeName = "x:Row" Then r = n.text
If n.nodeName = "x:Column" Then c = n.text
Next
Set rng = this.Cells(r + 1, c + 1)
productID = rng.Value
'now you have the productID, the fileName, and the cell location
End If
Next
End Sub
Let me know how that worked out for you.
If c4 contains your comment:
Set shp = Range("C4").Comment.Shape
if shp.Fill.TextureType = msoTextureUserDefined then
end if
Related
I have a file that is referencing 3 files outside of it. The problem is the outside files will have their version number changed when there is a change.
code is currently written to pull from C:documents/product_eval
01-Main_v1 is the main file that pulls
02-Address_v1
03_Products_v1
However, we now have a v2 for each of these files. I need a way to have file_03 always pull the 3rd file in the list of files, no matter what the version.
I feel like listing the code I tried will just confuse people, as it is so far off.
but here is the coding it will be feeding into
Sub LaunchBatching3_00(sourcePath As String, exportFolder As String, activeName As String)
Dim Adrs_PATH As String
Dim Prod_PATH As String
Adrs_PATH = Application.ActiveWorkbook.Path & "\02-Address_v1.xlms"
Prod_PATH = Application.ActiveWorkbook.Path & "\03-Products_v1.xlms"
Dim sFiles as Object, fFiles as Variant ,ppath as String, count as Long,
Set fFiles=CreateObject("Scripting.FileSystemObject")
set sFiles =fFiles.GetFolder(ppath)'get the folder object from folder path(variable ppath)
count=0
For Each x in sFiles.Files'loops all files in folder search for the last version by filename
If InStr(1,x.Name,"_v")>0 then
If CLng(Mid(x.Name,InStr(1,x.Name,"_v")+2,1))>count then count=CLng(Mid(x.Name,InStr(1,x.Name,"_v")+2,1))'gets the largest version
End If
Next x
For Each x in sFiles.Files
If CLng(Mid(x.Name,InStr(1,x.Name,"_v")+2,1)=If CLng(Mid(x.Name,InStr(1,x.Name,"_v")+2,1)=count then
'... fill your actions, for example,
Workbooks.Open FileName:=x.Name
End if
Next x
I'm trying to fill out template PDF with data from excel worksheet using VBA and here's what I have so far;
FILE_NAME_TEMPLATE = "path_to\template.pdf"
Set gApp = CreateObject("AcroExch.app")
Set avDoc = CreateObject("AcroExch.AVDoc")
If avDoc.Open(FILENAME, "") Then
Set pdDoc = avDoc.GetPDDoc()
Set jso = pdDoc.GetJSObject
'populating pdf fields here, no issues
FILE_NAME_RESULT = "path_to\result.pdf"
pdDoc.Save PDSaveFull, FILE_NAME_RESULT
pdDoc.Close
End If
avDoc.Close (True)
As is, code populates and saves template.pdf, however I'd like to leave template file unchanged and create the new result.pdf with populated data. Please explain what am I doing wrong and thank you for your time.
(Not enough points to just comment yet, so posting as an answer instead)
Is pdDoc.Close a Function and if so, what's its return value?
As a workaround, you could copy the template to the result file first and then work on the file.
FileCopy FILE_NAME_TEMPLATE, FILE_NAME_RESULT
Let me add a coding style best practice recommendation: use all upper-case names for constants only. For actual variables, use mixed case names (like you did with e.g. pdDoc.
I was looking for this too and it took me days: Just use the document flag (long) instead of the argument:
pdDoc.Save 1, FILE_NAME_RESULT
I have found some answers/examples here on stackoverflow for an issue where in Microsoft Excell 2010, I want to create a txt files for each cell from for e.g. ColumnA which would contain file names, and ColumnB which would contain what is inside certain text file, however one example doesn't work at all, and second bugs after few files created.
You can use the CreateTextFile method which will create your file and provide a TextStream object which you can use to write to the text files. Microsoft Docs
Here's a code example that will do what you asked.
Sub CreateTxt()
Dim my_range As Range
Dim pth As String
Set my_range = Selection
For Each x In my_range.Rows:
pth = "C:\excel_test\" + x.Cells(1) + ".txt" 'file name in column A
Set file_sys = CreateObject("Scripting.FileSystemObject")
Set txt_file = file_sys.CreateTextFile(pth, True)
txt_file.WriteLine (x.Cells(2)) 'content in Column B
txt_file.Close
Next x
End Sub
Just remember, in order to create a file you need adequate permissions on the path you're writing to - I had to run excel as administrator to get the functionality.
Also, the True value in the CreateTextFile method is necessary to overwrite any files with the existing file name, if set to false it will throw an error when trying to write to the file.
Before all, I want to say that I am not a programmer, so this may be basic for some people but surely not for me!!
The task that I want to accomplish is to retrieve some characters of a data file that is imported automatically from a server.
Data is stored in lines in a CSV or tabbed .txt file, each line consists of date and some numeric values. The format is always the same, only the file grows in one line each time a new value is entered.
What I need the script to do, is open that file (wich adress is known and constant) search for the last line, and then extract a string from that line and write it on a different .TXT file, from where I can import it to another specific software as a raw value.
The part in the middle (extracting string) is fairly simple, but opening and isolating the last line is far too much for me.
Thanks everybody for helping!
dim path
path = "fileName.txt"
otherOption(path)
function otherOption(fileName)
const read = 1
dim arrFileLines()
set objArgs = CreateObject("scripting.FileSystemObject")
if objArgs.FileExists(fileName) then
set objFile = objArgs.OpenTextFile(fileName,read)
i=0
do until objFile.AtEndOfStream
redim preserve arrFileLines(i)
arrFileLines(i) = objFile.ReadLine
i = i + 1
loop
objFile.Close
end if
wscript.Echo arrFileLines(i-1)
end function
I have used automation to insert values into a cell, however I have never seen any documentation, for example, that demonstrate inserting anything other than text and/or formula's.
Has anybody been able to insert an image from an external application?
Dim FileName as string
FileName="c:\text.jpg"
Set NewPic = ActiveSheet.Pictures.Insert(FileName)
NewPic.top=100
NewPic.left=100
If you want to position the picture to a specific cell then select that cell as a range and use that ranges top/left/with to position the picture.
Samples: http://exceltip.com/st/Insert_pictures_using_VBA_in_Microsoft_Excel/486.html
Note: In Excel cells cannot contain pictures. The pictures live on an invisible drawing layer that floats about the cells. They can be positioned based on the cell coordinates, which makes it feel like they are living "in" the cells.
I see it's already been answered, but see my post here.
Basically rather than use the Worksheet.Pictures.Insert method (which the MSDN recommends you don't use directly, and which returns a raw COM object), try the Worksheet.Shapes.AddPicture method instead.
Dim range As Microsoft.Office.Interop.Excel.Range
Dim pic as Microsoft.Office.Interop.Excel.Shape
Dim filePath as String
range = ...
filePath = ...
pic = range.Worksheet.Shapes.AddPicture(filePath, Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoCTrue, range.Left, range.Top, 300, 300)
It's not quite as straightforward because you have to specify the exact position and dimensions, but otherwise, pretty cool!
Sure, the following code gives a good example using the Microsoft Interop libraries:
string excelfilename = #"C:\excelfile.xlsx";
string picturename = #"C:\image.jpg";
object missing = Type.Missing;
Microsoft.Office.Interop.Excel.Application app = new ApplicationClass();
Workbook book = app.Workbooks.Add(missing);
Worksheet sheet = (Worksheet)book.ActiveSheet;
Pictures pics = (Pictures)sheet.Pictures(missing);
pics.Insert(picturename, missing);
book.SaveAs(excelfilename, missing, missing, missing, missing, missing, XlSaveAsAccessMode.xlNoChange,
missing, missing, missing, missing, missing);
app.Quit();
app = null;