I have to write a script that parses the images from ppt and dumps into excel. To do this, I first export all the images in the slides to a folder and then call excel Application to import them into the worksheet. The following code, which I found online, with my modifications is as follows:
Sub ExtractImagesFromPres()
Dim oSldSource As Slide
Dim oShpSource As Shape
Dim Ctr As Integer
Dim ObjExcel As Object
Dim wb As Object
Dim ws As Object
Set ObjExcel = CreateObject("Excel.Application")
Dim sPath As String
sPath = "C:\Users\Aravind_Sampathkumar\Documents\Expor"
Ctr = 0
Set wb = ObjExcel.Workbooks.Open("C:\Users\Aravind_Sampathkumar\Documents\Book1.xlsx")
Set ws = wb.Sheets(1)
'Open oPres.Path & PathSep & "Book1.CSV" For Output As iFile
For Each oSldSource In ActivePresentation.Slides
For Each oShpSource In oSldSource.Shapes
If oShpSource.Type = msoPicture Then
' Hidden Export method
Call oShpSource.Export(sPath & "Img" & Format(Ctr, "0000") & ".JPG", ppShapeFormatJPG)
Ctr = Ctr + 1
End If
Next oShpSource
Next oSldSource
Folderpath = "C:\Users\Aravind_Sampathkumar\Documents\Expor"
Set fso = CreateObject("Scripting.FileSystemObject")
NoOfFiles = fso.GetFolder(Folderpath).Files.Count
Set listfiles = fso.GetFolder(Folderpath).Files
counter = 1
For Each fls In listfiles
strCompFilePath = Folderpath & "\" & Trim(fls.Name)
If strCompFilePath <> "" Then
If (InStr(1, strCompFilePath, "jpg", vbTextCompare) > 1 _
Or InStr(1, strCompFilePath, "jpeg", vbTextCompare) > 1 _
Or InStr(1, strCompFilePath, "png", vbTextCompare) > 1) Then
counter = counter + 1
' ws.Range("C" & counter).Value = fls.Name
ws.Range("D" & counter).ColumnWidth = 25
ws.Range("D" & counter).RowHeight = 100
ws.Range("D" & counter).Activate
'Call insert(strCompFilePath, counter)
ws.Shapes.AddPicture strCompFilePath, True, True, 100,100,70,70
End If
End If
Next
'ws.Shapes.AddPicture ("C:\Users\Aravind_Sampathkumar\Documents")
'With .ShapeRange
' .LockAspectRatio = msoTrue
' .Width = 100
'.Height = 100
'End With
' .Left = ws.Cells(i, 20).Left
'.Top = ws.Cells(i, 20).Top
'.Placement = 1
'.PrintObject = True
'End With
End Sub
When I run it, the images get dumped into excel but all the images are overlapped on each other in the same cell. Is there any way I can modify it such that images go into consecutive rows? 1 image per row?
This puts them a row apart but you would need to size them appropriately. Note I changed your paths for test paths.
Option Explicit
Sub ExtractImagesFromPres()
Dim oSldSource As Slide
Dim oShpSource As Shape
Dim Ctr As Integer
Dim ObjExcel As Object
Dim wb As Object
Dim ws As Object
Set ObjExcel = CreateObject("Excel.Application")
Dim sPath As String
sPath = "C:\Users\User\Desktop\TestFolder" '"C:\Users\Aravind_Sampathkumar\Documents\Expor"
Ctr = 0
Set wb = ObjExcel.Workbooks.Open("C:\Users\User\Desktop\TestFolder\Test.xlsx") '("C:\Users\Aravind_Sampathkumar\Documents\Book1.xlsx")
ObjExcel.Visible = True
Set ws = wb.Sheets(1)
For Each oSldSource In ActivePresentation.Slides
For Each oShpSource In oSldSource.Shapes
If oShpSource.Type = msoPicture Then
Call oShpSource.Export(sPath & "\" & "Img" & Format(Ctr, "0000") & ".JPG", ppShapeFormatJPG)
Ctr = Ctr + 1
End If
Next oShpSource
Next oSldSource
Dim Folderpath As String
Dim fso As Object
Dim NoOfFiles As Long
Dim listfiles As Object
Dim counter As Long
Dim fls As Variant
Dim strCompFilePath As String
Folderpath = "C:\Users\User\Desktop\TestFolder" '"C:\Users\Aravind_Sampathkumar\Documents\Expor"
Set fso = CreateObject("Scripting.FileSystemObject")
NoOfFiles = fso.GetFolder(Folderpath).Files.Count
Set listfiles = fso.GetFolder(Folderpath).Files
counter = 1
For Each fls In listfiles
strCompFilePath = Folderpath & "\" & Trim(fls.Name)
If strCompFilePath <> vbNullString Then
If (InStr(1, strCompFilePath, "jpg", vbTextCompare) > 1 _
Or InStr(1, strCompFilePath, "jpeg", vbTextCompare) > 1 _
Or InStr(1, strCompFilePath, "png", vbTextCompare) > 1) Then
counter = counter + 1
' ws.Range("C" & counter).Value = fls.Name
ws.Range("D" & counter).ColumnWidth = 25
ws.Range("D" & counter).RowHeight = 100
ws.Range("D" & counter).Activate
'Call insert(strCompFilePath, counter)
With ws.Pictures.Insert(strCompFilePath)
.Left = ws.Cells(counter, "D").Left
.Top = ws.Cells(counter, "D").Top
End With
End If
End If
Next
End Sub
Have a look at the documentation for the AddPicture method:
https://msdn.microsoft.com/en-us/vba/excel-vba/articles/shapes-addpicture-method-excel
expression.AddPicture(Filename, LinkToFile, SaveWithDocument, Left, Top, Width, Height)
Rather than adding the picture at the active cell, it's location is controlled by the Left and Top arguments. You can use the Left and Top properties of the target cell as the arguments of the AddPicture method:
ws.Shapes.AddPicture strCompFilePath, True, True, ws.Range("D" & counter).Left, ws.Range("D" & counter).Top,70,70
Here's a version that uses copy/paste instead of export/import - it does include the line to change the row height if you want to crib just that.. :P
Sub ExtractImagesFromPres()
Dim oSldSource As Slide
Dim oShpSource As Shape
Dim ObjExcel As Object
Dim wb As Object
Dim ws As Object
Set ObjExcel = CreateObject("Excel.Application")
Dim lOffset AS Long
Set wb = ObjExcel.Workbooks.Open("C:\Users\Aravind_Sampathkumar\Documents\Book1.xlsx")
Set ws = wb.Sheets(1)
'Open oPres.Path & PathSep & "Book1.CSV" For Output As iFile
lOffset = 5
For Each oSldSource In ActivePresentation.Slides
For Each oShpSource In oSldSource.Shapes
If oShpSource.Type = msoPicture Then
oShpSource.Copy
ws.Paste
With ws.Shapes(ws.Shapes.Count)
.Top = lOffset
.Left = 5
.Placement = 3 'xlFreeFloating
'This line sets the row height!
.TopLeftCell.EntireRow.RowHeight = 10 + .Height
lOffset = lOffset + .Height + 10
End With
End If
Next oShpSource
Next oSldSource
'Optional Tidy-Up code
'Set ws = Nothing
'wb.Save
'Set wb = Nothing
'ObjExcel.Quit
'Set ObjExcel = Nothing
End Sub
I'm 100% certain you can export the images from PPT directly to XLS, but I'm not really sure how to do that. However, since you are able to export those images from PPT into a folder, and you just need help importing the images from there, I thin the code below will do just what you want.
Sub InsertPics()
Dim fPath As String, fName As String
Dim r As Range, rng As Range
Application.ScreenUpdating = False
fPath = "C:\your_path_here\"
Set rng = Range("A1:A" & Cells(Rows.Count, 1).End(xlUp).Row)
i = 1
For Each r In rng
fName = Dir(fPath)
Do While fName <> ""
If fName = r.Value Then
With ActiveSheet.Pictures.Insert(fPath & fName)
.ShapeRange.LockAspectRatio = msoTrue
Set px = .ShapeRange
If .ShapeRange.Width > Rows(i).Columns(2).Width Then .ShapeRange.Width = Columns(2).Width
With Cells(i, 2)
px.Top = .Top
px.Left = .Left
.RowHeight = px.Height
End With
End With
End If
fName = Dir
Loop
i = i + 1
Next r
Application.ScreenUpdating = True
End Sub
' Note: you need the file extension, such as ',jpg', or whatever you are using, so you can match on that.
Sub Insert()
Dim strFolder As String
Dim strFileName As String
Dim objPic As Picture
Dim rngCell As Range
strFolder = "C:\Users\Public\Pictures\Sample Pictures\" 'change the path accordingly
If Right(strFolder, 1) <> "\" Then
strFolder = strFolder & "\"
End If
Set rngCell = Range("E1") 'starting cell
strFileName = Dir(strFolder & "*.jpg", vbNormal) 'filter for .png files
Do While Len(strFileName) > 0
Set objPic = ActiveSheet.Pictures.Insert(strFolder & strFileName)
With objPic
.Left = rngCell.Left
.Top = rngCell.Top
.Height = rngCell.RowHeight
.Placement = xlMoveAndSize
End With
Set rngCell = rngCell.Offset(1, 0)
strFileName = Dir
Loop
End Sub
Related
I am completely new to VBA, but I have CSV files(same format for all of them), and I want to import them to a single sheet on Excel. I was able to read the CSV file according to this code:
Sub R_AnalysisMerger()
Dim WSA As Worksheet
Dim bookList As Workbook
Dim SelectedFiles() As Variant
Dim NFile As Long
Dim FileName As String
Dim ws As Worksheet, vDB As Variant, rngT As Range
Application.ScreenUpdating = False
'Selects the CSV files as SELECTED FILES
Set ws = ThisWorkbook.Sheets(1)
ws.UsedRange.Clear 'Clears current worksheet
SelectedFiles = Application.GetOpenFilename(filefilter:="Excel Files (*.csv*), *.csv*", MultiSelect:=True) 'Selects csv files
For NFile = LBound(SelectedFiles) To UBound(SelectedFiles)
FileName = SelectedFiles(NFile)
Set bookList = Workbooks.Open(FileName, Format:=2)
Set WSA = bookList.Sheets(1)
With WSA
vDB = .UsedRange
Set rngT = ws.Range("a" & Rows.count).End(xlUp)(2)
If rngT.Row = 2 Then Set rngT = ws.Range("A1")
rngT.Resize(UBound(vDB, 1), UBound(vDB, 2)) = vDB
bookList.Close (0)
End With
Next
Application.ScreenUpdating = True
ws.Range("A1").Select
But I have additional requirements:
Skip the first column.
Skip the first four rows.
Remove a certain String from each word in the fifth row.
Im used to java, and usually I would read each line with a "for" loop and set "if" statements to skip the first row and four columns and remove the string from each string if it was present.
I don't know how to do this with this code. From what I understand it just copies the whole CSV file into the sheet?
This solution is based on reading CSV as textstream. I have tried to include feature that makes possible most all things like selecting columns, Rows and so on.
Sub ImportCSV()
Dim fso As New IWshRuntimeLibrary.FileSystemObject
Dim txtStream As IWshRuntimeLibrary.TextStream
Dim files As IWshRuntimeLibrary.files
Dim file As IWshRuntimeLibrary.file
Dim txtLine As String
Dim lineCount As Integer
Dim lastRow As Integer
Dim lineCol As Variant
Dim rng As Range
Application.ScreenUpdating = False
ThisWorkbook.Sheets(1).usedRange.Delete
Set rng = ThisWorkbook.Sheets(1).usedRange
lastRow = 1
Set files = fso.GetFolder("path\folder").files
For Each file In files
If file.Name Like "*.csv" Then
Set txtStream = file.OpenAsTextStream(ForReading, TristateUseDefault)
txtStream.SkipLine ' skip first line, since it containes headers
lineCount = 1
Do
txtLine = txtStream.ReadLine
If lineCount = 5 Then
txtLine = Replace(txtLine, "stringToReplace", "StringToReplcaeWith") ' replace certain string from words in 5'th row
End If
lineCount = lineCount + 1
lineCol = sliceStr(Split(txtLine, ";"), startIdx:=4) ' slice the array so to skip four first columns
For iCol = 0 To UBound(lineCol) ' write columns to last row
rng(lastRow, iCol + 1).Value = lineCol(iCol)
Next iCol
lastRow = lastRow + 1
'Debug.Print Join(lineCol, ";") ' debug
Loop Until txtStream.AtEndOfStream
End If
Next file
Application.ScreenUpdating = True
End Sub
This is the slicer function
Function sliceStr(arr As Variant, startIdx As Integer, Optional stopIdx As Integer = 0) As String()
If stopIdx = 0 Then
stopIdx = UBound(arr)
End If
Dim tempArrStr() As String
ReDim tempArrStr(stopIdx - startIdx)
Dim counter As Integer
counter = 0
For i = startIdx To stopIdx
tempArrStr(counter) = arr(i)
counter = counter + 1
Next
sliceStr = tempArrStr
End Function
I just did a simple test and the code below seems to work. Give it a go, and feedback.
Sub Demo()
Dim fso As Object 'FileSystemObject
Dim fldStart As Object 'Folder
Dim fld As Object 'Folder
Dim fl As Object 'File
Dim Mask As String
Application.ScreenUpdating = False
Dim newWS As Worksheet
Set newWS = Sheets.Add(before:=Sheets(1))
Set fso = CreateObject("scripting.FileSystemObject") ' late binding
'Set fso = New FileSystemObject 'or use early binding (also replace Object types)
Set fldStart = fso.GetFolder("C:\Users\ryans\OneDrive\Desktop\output\") ' <-- use your FileDialog code here
Mask = "*.csv"
'Debug.Print fldStart.Path & ""
ListFiles fldStart, Mask
For Each fld In fldStart.SubFolders
ListFiles fld, Mask
ListFolders fld, Mask
Next
Dim myWB As Workbook, WB As Workbook
Set myWB = ThisWorkbook
Dim L As Long, t As Long, i As Long
L = myWB.Sheets(1).Cells(Rows.Count, "A").End(xlUp).Row
t = 1
For i = 1 To L
Workbooks.OpenText Filename:=myWB.Sheets(1).Cells(i, 1).Value, DataType:=xlDelimited, Tab:=True
Set WB = ActiveWorkbook
lrow = WB.Sheets(1).Cells(Rows.Count, "A").End(xlUp).Row
WB.Sheets(1).Range("B4:E" & lrow).Copy newWS.Cells(t, 2)
t = myWB.Sheets(1).Cells(Rows.Count, "B").End(xlUp).Row + 1
WB.Close False
Next
myWB.Sheets(1).Columns(1).Delete
Application.ScreenUpdating = True
End Sub
Sub ListFolders(fldStart As Object, Mask As String)
Dim fld As Object 'Folder
For Each fld In fldStart.SubFolders
'Debug.Print fld.Path & ""
ListFiles fld, Mask
ListFolders fld, Mask
Next
End Sub
Sub ListFiles(fld As Object, Mask As String)
Dim t As Long
Dim fl As Object 'File
For Each fl In fld.Files
If fl.Name Like Mask Then
t = Sheets(1).Cells(Rows.Count, "A").End(xlUp).Row + 1
'Debug.Print fld.Path & "" & fl.Name
If Sheets(1).Cells(1, 1) = "" Then
Sheets(1).Cells(1, 1) = fld.Path & "\" & fl.Name
Else
Sheets(1).Cells(t, 1) = fld.Path & "\" & fl.Name
End If
End If
Next
End Sub
I am trying to open each file listed in Sheet2 Column A, search for a string of text located in Sheet3 Cell B1, list the number of instances this string appears in each particular file in Sheet3, and then close the file.
My code works at the moment, but is very slow and sometimes creates errors which makes everything even slower. I have tens of thousands of files that need searching, so speed is just as important as performance.
Is there a way to complete this task more efficiently than what I am already doing? Bonus points for removing any possible error sources. Thanks in advance.
Sub FindMe()
Dim fle As Range
Dim i As Long
Dim k As Long
Dim line As Long
Dim strline As String
Dim strsearch As String
Dim loc As Range
Dim sht As Worksheet
Dim lngPos As Long
Dim lngCount As Long
Dim wdApp As Object
Dim wdDoc As Object
Dim oRng As Object
Dim osld As Object
Dim oshp As Object
Dim pptApp As Object
Dim pptdoc As Object
Sheet3.Range("A4:B999999").ClearContents
Application.ScreenUpdating = False
Application.DisplayAlerts = False
If Not IsEmpty(Sheet3.Range("B1").Value) Then
strsearch = Sheet3.Range("B1").Value
i = 0
k = 4
lngCount = 0
For Each fle In Sheet2.Range("A:A")
If InStr(1, fle.Value, ".txt") > 0 Then '.txt extension
Open fle.Value For Input As #1
Do While Not EOF(1)
Line Input #1, strline
lngPos = 1
Do
lngPos = InStr(lngPos, strline, strsearch, vbTextCompare)
If lngPos > 0 Then
lngCount = lngCount + 1
lngPos = lngPos + Len(strsearch)
End If
Loop Until lngPos = 0
Loop
If lngCount <> 0 Then
Sheet3.Cells(k, 1).Value = lngCount
Sheet3.Cells(k, 2).Value = fle.Value
k = k + 1
lngCount = 0
End If
Close #1
ElseIf InStr(1, fle.Value, ".xls") > 0 Or InStr(1, fle.Value, ".csv") Then '.xls, .xlsx, .xlsm, .csv extentions
Workbooks.Open Filename:=fle.Value, ReadOnly:=True, UpdateLinks:=False
For Each sht In ActiveWorkbook.Worksheets
With sht
Set loc = .Cells.Find(What:=strsearch)
If Not loc Is Nothing Then
FirstAddress = loc.Address
Do
i = i + 1
Set loc = .Cells.FindNext(loc)
Loop While Not loc Is Nothing And loc.Address <> FirstAddress
End If
End With
Next sht
ActiveWorkbook.Close False
If i <> 0 Then
Sheet3.Cells(k, 1).Value = i
Sheet3.Cells(k, 2).Value = fle.Value
k = k + 1
i = 0
End If
ElseIf InStr(1, fle.Value, ".doc") > 0 Or InStr(1, fle.Value, ".pdf") > 0 Then '.doc, .docx extentions
Set wdApp = CreateObject("word.Application")
Set wdDoc = wdApp.documents.Open(fle.Value, ReadOnly:=True)
Set oRng = wdDoc.Range
With oRng.Find
Do While .Execute(FindText:=strsearch, MatchCase:=False)
i = i + 1
Loop
End With
wdDoc.Close 0
Set oRng = Nothing
Set wdDoc = Nothing
Set wdApp = Nothing
If i <> 0 Then
Sheet3.Cells(k, 1).Value = i
Sheet3.Cells(k, 2).Value = fle.Value
k = k + 1
i = 0
End If
ElseIf InStr(1, fle.Value, ".ppt") > 0 Then '.ppt, .pptx, .pptm extentions
Set pptApp = CreateObject("powerpoint.Application")
Set pptdoc = pptApp.presentations.Open(fle.Value, ReadOnly:=True)
For Each osld In pptdoc.slides
For Each oshp In osld.Shapes
If oshp.HasTextFrame Then
If oshp.TextFrame.HasText Then
Set otext = oshp.TextFrame.TextRange
Set foundText = otext.Find(findwhat:=strsearch)
Do While Not (foundText Is Nothing)
lngCount = lngCount + 1
With foundText
Set foundText = otext.Find(findwhat:=strsearch, After:=.Start + .Length - 1)
End With
Loop
End If
End If
Next oshp
Next osld
pptdoc.Close
Set pptdoc = Nothing
Set pptApp = Nothing
Set otext = Nothing
Set foundText = Nothing
If lngCount <> 0 Then
Sheet3.Cells(k, 1).Value = lngCount
Sheet3.Cells(k, 2).Value = fle.Value
k = k + 1
lngCount = 0
End If
End If
Next fle
Else:
MsgBox "Enter text in cell 'B1' before searching."
End If
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
I have a form in ms word with some of the fields are content control and some (which are the radio buttons) are ActiveX control. I want to automatically transfer hundred word forms to an excel file. I use the following vba code:
Sub getWordFormData()
Dim wdApp As New Word.Application
Dim myDoc As Word.Document
Dim CCtl As Word.ContentControl
Dim myFolder As String, strFile As String
Dim myWkSht As Worksheet, i As Long, j As Long
myFolder = "C:\Users\alarfajal\Desktop\myform"
Application.ScreenUpdating = False
If myFolder = "" Then Exit Sub
Set myWkSht = ActiveSheet
ActiveSheet.Cells.Clear
Range("A1") = "name"
Range("a1").Font.Bold = True
Range("B1") = "age"
Range("B1").Font.Bold = True
Range("C1") = "gender"
Range("C1").Font.Bold = True
Range("D1") = "checkbox1"
Range("D1").Font.Bold = True
Range("E1") = "checkbox2"
Range("E1").Font.Bold = True
Range("F1") = "singlechoice1"
Range("F1").Font.Bold = True
Range("G1") = "singlechoice2"
Range("G1").Font.Bold = True
i = myWkSht.Cells(myWkSht.Rows.Count, 1).End(xlUp).Row
strFile = Dir(myFolder & "\*.docx", vbNormal)
While strFile <> ""
i = i + 1
Set myDoc = wdApp.Documents.Open(Filename:=myFolder & "\" & strFile, AddToRecentFiles:=False, Visible:=False)
With myDoc
j = 0
For Each CCtl In .ContentControls
j = j + 1
myWkSht.Cells(i, j) = CCtl.Range.Text
Next
myWkSht.Columns.AutoFit
End With
myDoc.Close SaveChanges:=False
strFile = Dir()
Wend
wdApp.Quit
Set myDoc = Nothing: Set wdApp = Nothing: Set myWkSht = Nothing
Application.ScreenUpdating = True
End Sub
all the data (text fields, checkbox) are transferred successfully but, the radio button (which is ActiveX) is not transferred.
This is the word doc:
This is the excel result:
How can I solve this problem?
You can refer to an ActiveX control on a Word document by it's name
myDoc.singlechoice1.Value
It is better to refer to the ContentControls by their tag names.
myDoc.SelectContentControlsByTag("name").Item(1).Range.Text
Refactored Code
Sub getWordFormData()
Dim wdApp As Object, myDoc As Object
Dim myFolder As String, strFile As String
Dim i As Long, j As Long
myFolder = "C:\Users\alarfajal\Desktop\myform"
If Len(Dir(myFolder)) = 0 Then
MsgBox myFolder & vbCrLf & "Not Found", vbInformation, "Cancelled - getWordFormData"
Exit Sub
End If
Application.ScreenUpdating = False
Set wdApp = CreateObject("Word.Application")
With ActiveSheet
.Cells.Clear
With .Range("A1:G1")
.Value = Array("name", "age", "gender", "checkbox1", "checkbox2", "singlechoice1", "singlechoice2")
.Font.Bold = True
End With
strFile = Dir(myFolder & "\*.docx", vbNormal)
i = 1
While strFile <> ""
i = i + 1
Set myDoc = wdApp.Documents.Open(Filename:=myFolder & "\" & strFile, ReadOnly:=True, AddToRecentFiles:=False, Visible:=False)
.Cells(i, 1).Value = myDoc.SelectContentControlsByTag("name").Item(1).Range.Text
.Cells(i, 2).Value = myDoc.SelectContentControlsByTag("age").Item(1).Range.Text
.Cells(i, 3).Value = myDoc.SelectContentControlsByTag("gender").Item(1).Range.Text
.Cells(i, 4).Value = myDoc.SelectContentControlsByTag("checkbox1").Item(1).Checked
.Cells(i, 5).Value = myDoc.SelectContentControlsByTag("checkbox2").Item(1).Checked
.Cells(i, 6).Value = myDoc.singlechoice1.Value
.Cells(i, 7).Value = myDoc.singlechoice2.Value
myDoc.Close SaveChanges:=False
strFile = Dir()
Wend
wdApp.Quit
Application.ScreenUpdating = True
End With
End Sub
Your radiobuttons are inlineshapes so you need a separate loop for them
to keep in line with your current code, it would be something like
Dim shp As InlineShape
For Each shp In .InlineShapes
j = j + 1
myWkSht.Cells(i, j) = shp.OLEFormat.Object.Value
Next shp
However I wouldn't want to rely on Word always giving me the right order and there could be other inlineshapes so it might be better to check the controls first:
With myDoc
'content controls
For Each CCtl In .ContentControls
Select Case CCtl.Title
Case "name"
myWkSht.Cells(i, 1) = CCtl.Range.Text
'similar for age and gender
Case "checkbox1"
myWkSht.Cells(i, 4) = CCtl.Checked 'true and false are easier to evaluate in Excel than the checkmark symbols
'same for checkbox 2
End Select
Next CCtl
'option buttons
For Each shp In .InlineShapes
If shp.Type = wdInlineShapeOLEControlObject Then 'skip other inlineshapes
Select Case shp.OLEFormat.Object.Name
Case "singleSelectQuestionOption1" 'name it something unique
myWkSht.Cells(i, 6) = shp.OLEFormat.Object.Value
'similar for option button 2
End Select
End If
Next shp
End With
I wanted to write a code for macro, that will load files from my local directory into excel sheet of Column say ("C"), the names on files should match names on Column ("B"). If any of the files doesn't find for the names given in column B it should skip that row of loading files and continues to next column. I'am difficulty in writing as I am new to VB. I tried somehow but, my script working to load files from directory and loading names. Please help!! thank you all,
Code:
Sub Insert_OLE_Object()
Dim mainWorkBook As Workbook
Set mainWorkBook = ActiveWorkbook
Set ActiveSheet = example1
Folderpath = "C:\Documents and Settings\my\Desktop\folder1"
Set fso = CreateObject("Scripting.FileSystemObject")
NoOfFiles = fso.GetFolder(Folderpath).Files.Count
Set listfiles = fso.GetFolder(Folderpath).Files
For Each fls In listfiles
Counter = Counter + 1
Range("B" & Counter).Value = fls.Name
strCompFilePath = Folderpath & "\" & Trim(fls.Name)
If strCompFilePath <> "" Then
Worksheets("Example1").OLEObjects.Add(Filename:=strCompFilePath, Link:=False, DisplayAsIcon:=True, IconIndex:=1, IconLabel:=strCompFilePath, Left:=20, Top:=40, Width:=150, Height:=10).Select
Sheets("example1").Activate
Sheets("example1").Range("C" & ((Counter - 1) * 3) + 1).Select
End If
Next
End Sub
Try this code:
Sub Insert_OLE_Object()
Dim ws As Worksheet
Dim rng As Range, c As Range
Dim strCompFilePath As String, Folderpath As String, fullpath As String
Dim obj As Object
Application.ScreenUpdating = False
'change to suit
Set ws = ThisWorkbook.Worksheets("Example1")
'change B1:B5 to suit
Set rng = ws.Range("B1:B5")
Folderpath = "C:\Documents and Settings\my\Desktop\folder1"
For Each c In rng
strCompFilePath = Dir(Folderpath & "\" & Trim(c.Value) & ".*")
'if file with this name found, embed it
If strCompFilePath <> "" Then
fullpath = Folderpath & "\" & strCompFilePath
Set obj = ws.OLEObjects.Add(Filename:=fullpath, Link:=False, _
DisplayAsIcon:=True, IconIndex:=1, _
IconLabel:=fullpath)
With obj
.Left = c.Offset(, 1).Left
.Top = c.Offset(, 1).Top
.Width = c.Offset(, 1).ColumnWidth
.Height = c.Offset(, 1).RowHeight
End With
End If
Next
Application.ScreenUpdating = True
End Sub
Given a folder tree:
c:\example\
c:\example\2014-01-01\
c:\example\2014-01-01\Entered\
c:\example\2014-01-02\
c:\example\2014-01-02\Entered
etc.
I want to count the PDF files in the tree, but excluding any in the "Entered\" subfolders.
Is this possible even with VBA? Ultimately this count needs to be spit out onto an excel sheet.
copy all the code in an Excel-VBA Module. If you want to use a button then you should use CntFiles() on the button. But if you don't want to use a button then you can use fCount(strPath) as a formula on the Worksheet i.e =fCount("your-path"), the parameter is String so make it double-quoted when using on Worksheet.
Function fCount(strPath)
Dim fCnt As Integer
fCnt = ShowFolderList(strPath)
fCount = fCnt
End Function
Sub CntFiles()
Dim strPath As String
strPath = "A:\Asif\Answers\abc"
ShowFolderList (strPath)
End Sub
Function ShowFolderList(Path)
Dim fso, folder, subFlds, fld
Dim tFiles As Integer
tFiles = ShowFilesList(Path)
Set fso = CreateObject("Scripting.FileSystemObject")
Set folder = fso.GetFolder(Path)
Set subFlds = folder.SubFolders
For Each fld In subFlds
If fld.Name = "Entered" Then
GoTo SkipFld:
Else
Path = fld.Path
tFiles = tFiles + ShowFilesList(Path)
End If
SkipFld:
Next
'MsgBox tFiles & " files"
ShowFolderList = tFiles
End Function
Function ShowFilesList(folderspec)
Dim fso, f, f1, fc, s
Dim Cnt As Integer
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFolder(folderspec)
Set fc = f.Files
For Each f1 In fc
If GetAnExtension(f1) = "pdf" Then
Cnt = Cnt + 1
Else
End If
Next
ShowFilesList = Cnt
End Function
Function GetAnExtension(DriveSpec)
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
GetAnExtension = fso.GetExtensionName(DriveSpec)
End Function
This code will count all the files in the specified folder as well as sub-folders excluding folder named "Entered" as you specified.
This code gives you a nice overview in an excel sheet:
Sub start()
Application.ScreenUpdating = False
Dim FolderName As String
Sheets("fldr").Select
Cells(1, 1).Value = 2
With Application.FileDialog(msoFileDialogFolderPicker)
.AllowMultiSelect = False
.Show
On Error Resume Next
FolderName = .SelectedItems(1)
Err.Clear
On Error GoTo 0
End With
ListFolders (FolderName)
Application.ScreenUpdating = True
MsgBox "Done" & vbCrLf & "Total files found: " & Cells(1, 1).Value
Cells(1, 1).Value = "Source"
Cells(1, 2).Value = "Folder"
Cells(1, 3).Value = "Subfolder"
Cells(1, 4).Value = "FileCount"
End Sub
Sub ListFolders(Fldr As String)
Dim fs
Set fs = CreateObject("Scripting.FileSystemObject")
Dim fl1
Set fl1 = CreateObject("Scripting.FileSystemObject")
Dim fl2
Set fl2 = CreateObject("Scripting.FileSystemObject")
Set fl1 = fs.GetFolder(Fldr)
For Each fl2 In fl1.SubFolders
Cells(Cells(1, 1).Value, 1).Value = Replace(Fldr, fl1.Name, "")
Cells(Cells(1, 1).Value, 2).Value = fl1.Name
Cells(Cells(1, 1).Value, 3).Value = fl2.Name
Cells(Cells(1, 1).Value, 4).Value = CountFiles(Fldr & "\" & fl2.Name)
Cells(1, 1).Value = Cells(1, 1).Value + 1
ListFolders fl2.Path
Next
End Sub
Function CountFiles(Fldr As String)
Dim fso As Object
Dim objFiles As Object
Dim obj As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Set objFiles = fso.GetFolder(Fldr).Files
CountFiles = objFiles.Count
Set objFiles = Nothing
Set fso = Nothing
Set obj = Nothing
End Function