I'm writing VBA program in powerpoint
The flow of program: VBA powerpoint macro have to open the excel file and copy and replace cell content to the specific shape in a specific slide.
Here the excel file has 21 columns. I have to copy and replace cell data to slide shape in slide #8. How to increment the cell value horizontally? Like a1 to b1 till 21 cells and repeat the same from beginning
here the code
Sub xltoppt()
Dim xlApp As Object
Dim xlWorkBook As Object
Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = True
Set xlWorkBook = xlApp.Workbooks.Open("C:\Users\\Desktop\test.xls", True, False)
Set xlApp = Nothing
Set xlWorkBook = Nothing
Dim SheetName As String
Dim TestRange As Range
Dim TestSheet As Worksheet
Dim PasteRange As Boolean
Dim RangePasteType As String
Dim RangeName As String
Dim AddSlidesToEnd As Boolean
Dim shts As Worksheet
Dim sld As Slide
Dim grpItem As Shape
Dim shp As Shape
Dim i As Long
Dim j As Long
SheetName = ActiveSheet.Name
'Setting PasteRange to True means that Chart Option will not be used
PasteRange = True
RangeName = ("B1:B1") '"MyRange"
RangePasteType = "HTML"
RangeLink = True
PasteChart = False
PasteChartLink = True
ChartNumber = 1
AddSlidesToEnd = True
'Error testing
On Error Resume Next
Set TestSheet = Sheets(SheetName)
Set TestRange = Sheets(SheetName).Range(RangeName)
Set TestChart = Sheets(SheetName).ChartObjects(ChartNumber)
On Error GoTo 0
'If TestSheet Is Nothing Then
'MsgBox "Sheet " & SheetName & " does not exist. Macro will exit", vbCritical
Exit Sub
'End If
'If PasteRange And TestRange Is Nothing Then
MsgBox "Range " & RangeName & " does not exist. Macro will exit", vbCritical
Exit Sub
'End If
'Look for existing instance
'On Error Resume Next
'Set ppApp = GetObject(, "PowerPoint.Application")
'On Error GoTo 0
'Create new instance if no instance exists
''If ppApp Is Nothing Then Set ppApp = New PowerPoint.Application
'Add a presentation if none exists
'If ppApp.Presentations.Count = 0 Then ppApp.Presentations.Add
'Make the instance visible
ppApp.Visible = True
'Check that a slide exits, if it doesn't add 1 slide. Else use the last slide for the paste operation
For Each sld In ActivePresentation.Slides
For Each shp In sld.Shapes
If shp.HasTextFrame Then
If shp.TextFrame.HasText Then
shp.TextFrame.TextRange.Text = replace(shp.TextFrame.TextRange.Text, "happy", Worksheets(SheetName).Range(RangeName))
End If
End If
Next shp
Next
End Sub```
Related
I'm trying to create a new sheet labeled with a different identifier from a range and also have two cells from other ranges included on each update. I can get the new sheets to create with a different label from a range, and have the first cell in the second range (xRg2) added to each subsequent sheet, but haven't been successful at iterating through the second range. I know I need another loop somewhere but my last nest created way too many sheet. See example below
Sub Add()
Dim xRg As Excel.Range
Dim xRg2 As Excel.Range
Dim wSh As Excel.Worksheet
Dim wBk As Excel.Workbook
Dim wSh2 As Excel.Worksheet
Dim wSh3 As Excel.Worksheet
Set wSh = ActiveSheet
Set wBk = ActiveWorkbook
Set wSh2 = ThisWorkbook.Sheets("List")
Set wSh3 = ThisWorkbook.Sheets("Template")
Set xRg2 = wSh2.Range("G66:G88")
Application.ScreenUpdating = False
For Each xRg In wSh2.Range("B66:B88")
With wBk
wSh3.Copy after:=.Sheets(.Sheets.Count)
On Error Resume Next
wSh.Name = xRg.Value
wSh.Cells(33,7) = xRg2.Value
If Err.Number = 1004 Then
Debug.Print xRg.Value & "already used as a sheet name"
End If
On Error GoTo 0
End With
Next xRg
Application.ScreenUpdating = True End Sub
So, to summarize, the goal here is to input the ranges into the code each time and have each new sheet include the first values from each range, then the second sheet the second values from each range, and so on until the xRg is at the end of it's list. I know there's only two ranges down here but the total will be 3. Also apologies on the poor variable discipline...
Thanks!
Try something like this (sorry do not like all those x... variable names)
Sub Add()
Dim c As Range
Dim wb As Workbook, ws As Worksheet, wsList As Worksheet
Set wb = ActiveWorkbook
Set wsList = wb.Worksheets("List")
Application.ScreenUpdating = False
For Each c In wsList.Range("B66:B88").Cells
ThisWorkbook.Sheets("Template").Copy after:=wb.Sheets(wb.Sheets.Count)
Set ws = wb.Sheets(wb.Sheets.Count) '<< get the just-created sheet copy
On Error Resume Next
ws.Name = c.Value
ws.Cells(33, 7) = c.EntireRow.Columns("G").Value
If Err.Number = 1004 Then
Debug.Print "'" & c.Value & "' already used as a sheet name"
End If
On Error GoTo 0
Next c
Application.ScreenUpdating = True
End Sub
I'm trying to run this code in excel from another application.The code runs without problems, however rngNumber.Copy wsData.Range("A2") isn't copied. I've tested the same code directly in excel and it was copied perfectly. I think that maybe rngNumber isn't set properly when the code is runned from another application. But, I don't get exactly the reason. Any suggestion would be appreciate, thanks.
Sub TEST()
' Try to connect to a running instance of Excel.
Dim excelApp As Excel.Application
On Error Resume Next
Set excelApp = GetObject(, "Excel.Application")
If Err Then
Err.Clear
' Couldn't connect so start Excel. It's started invisibly.
Set excelApp = CreateObject("Excel.Application")
If Err Then
MsgBox "Cannot access excel."
Exit Sub
End If
End If
' You can make it visible if you want. This is especially
' helpful when debugging.
excelApp.Visible = True
'Open the excel file (through dialog)
Dim ExcelFilePath As Variant
ExcelFilePath = excelApp.GetOpenFilename(FileFilter:="Excel Files,*.xl*;*.xm*")
If ExcelFilePath <> False Then
Set wb = excelApp.Workbooks.Open(ExcelFilePath)
End If
' Open the excel file
Dim wb as Workbook
Set wb = excelApp.ActiveWorkbook
Dim ws as Worksheet
Set ws = wb.Worksheets(1)
ws.Activate
'Set Worksheet
Dim wsData As WorkSheet
Set wsData = wb.Worksheets(2)
'Write column titles
With wsData
.Cells(1, "A").Value = "Number"
End With
'Get column letter for each column whose first row starts with an specific string
ws.Activate
Dim sNumber as String
sNumber= Find_Column("Number")
'Define variables
Dim rngNumber As Range
' Copy and paste data from "Number" column to Column "A" in Worksheets "Data"
ws.Activate
'Find which is the last row with data in "Number" column and set range
With ws.Columns(sNumber)
Set rngNumber = Range(.Cells(2), .Cells(.Rows.Count).End(xlUp))
End With
'Copy and paste data from "Number" column
rngNumber.Copy wsData.Range("A2")
End Sub
Private Function Find_Column(Name As String) As String
Dim rngName As Range
Dim Column As String
With ws.Rows(1)
On Error Resume Next
Set rngName = .Find(Name, .Cells(.Cells.Count), xlValues, xlWhole)
' Calculate Name Column Letter.
Find_Column = Split(rngName.Address, "$")(1)
End With
End Function
Explicitly define the excel object and remove the On Error Resume Next. This works from Word.
Option Explicit
Sub TEST()
' Try to connect to a running instance of Excel.
Dim excelApp As Excel.Application
Dim wb As Excel.Workbook
Dim ws As Excel.WorkSheet, wsData As Excel.WorkSheet
Dim rngNumber As Excel.Range
On Error Resume Next
Set excelApp = GetObject(, "Excel.Application")
If Err Then
Err.Clear
' Couldn't connect so start Excel. It's started invisibly.
Set excelApp = CreateObject("Excel.Application")
If Err Then
MsgBox "Cannot access excel."
Exit Sub
End If
End If
On Error GoTo 0
' You can make it visible if you want. This is especially
' helpful when debugging.
excelApp.Visible = True
excelApp.WindowState = xlMinimized
'Open the excel file (through dialog)
Dim ExcelFilePath As Variant
ExcelFilePath = excelApp.GetOpenFilename(FileFilter:="Excel Files,*.xl*;*.xm*")
If ExcelFilePath = False Then
MsgBox "No file not selected"
Exit Sub
End If
Set wb = excelApp.Workbooks.Open(ExcelFilePath)
Set ws = wb.Sheets(1)
Set wsData = wb.Sheets(2)
' Get column letter for each column whose first row
' starts with an specific string
Dim sNumber As String, LastRow As Long
sNumber = Find_Column(ws, "Number")
If sNumber = "#N/A" Then
MsgBox "Column 'Number' not found in " & vbLf & _
"Wb " & wb.Name & " Sht " & ws.Name, vbExclamation
Exit Sub
End If
' Copy and paste data from "Number" column to Column "A" in Worksheets "Data"
' Find which is the last row with data in "Number" column and set range
With ws
LastRow = .Cells(.Rows.Count, sNumber).End(xlUp).Row
Set rngNumber = .Cells(1, sNumber).Resize(LastRow)
End With
'Copy and paste data from "Number" column
rngNumber.Copy wsData.Range("A1")
excelApp.WindowState = xlMinimized
MsgBox LastRow & " rows copied from column " & sNumber, vbInformation
End Sub
Private Function Find_Column(ws, Name As String) As String
Dim rngName As Excel.Range
With ws.Rows(1)
Set rngName = .Find(Name, After:=.Cells(.Cells.Count), _
LookIn:=xlValues, lookat:=xlWhole)
End With
If rngName Is Nothing Then
Find_Column = "#N/A"
Else ' Calculate Name Column Letter.
Find_Column = Split(rngName.Address, "$")(1)
End If
End Function
I am trying to prepare a presentation from Excel. As of now VBA code is preparing "n number of "presentations as per no of times Loop runs. I want Code to generate just 1 presentation with all slides combined. Fist Macro "Addnumber" is run, which run Macro "ExcelRangeToPowerPoint". Its Macro "ExcelRangeToPowerPoint"which need to add slides for every loop of Macro "Addnumber"
Please Support
Sub AddNumber()
Dim Ws As Worksheet
Dim rngSel As Range
Dim rng As Range
Dim Num As Double
Dim i As Long
Dim j As Long
Dim lAreas As Long
Dim lRows As Long
Dim lCols As Long
Dim Arr() As Variant
Set rngSel = Worksheets("Sheet1").Range("A5:A30")
Do Until Range("A30") = Range("A3")
Num = 26
For Each rng In rngSel.Areas
If rng.Count = 1 Then
rng = rng + Num
Else
lRows = rng.Rows.Count
lCols = rng.Columns.Count
Arr = rng
For i = 1 To lRows
For j = 1 To lCols
Arr(i, j) = Arr(i, j) + Num
Next j
Next i
rng.Value = Arr
End If
Call ExcelRangeToPowerPoint
Next rng
Loop
End Sub
Sub ExcelRangeToPowerPoint()
'PURPOSE: Copy/Paste An Excel Range Into a New PowerPoint Presentation
Dim rng As Range
Dim rng2 As Range
Dim PowerPointApp As Object
Dim myPresentation As Object
Dim mySlide As Object
Dim myShape As Object
Dim mySize As PageSetup
Dim Addtitle As Shape
Dim DateT As String
'Copy Range from Excel
Set rng = Worksheets("Sheet1").Range("E2:M30")
Set rng2 = Worksheets("Sheet1").Range("F2")
Set rng3 = Worksheets("Sheet1").Range("B3")
'Create an Instance of PowerPoint
On Error Resume Next
'Is PowerPoint already opened?
Set PowerPointApp = GetObject(class:="PowerPoint.Application")
'Clear the error between errors
Err.Clear
'If PowerPoint is not already open then open PowerPoint
If PowerPointApp Is Nothing Then Set PowerPointApp = CreateObject(class:="PowerPoint.Application")
'Handle if the PowerPoint Application is not found
If Err.Number = 429 Then
MsgBox "PowerPoint could not be found, aborting."
Exit Sub
End If
On Error GoTo 0
'Optimize Code
Application.ScreenUpdating = False
'Create a New Presentation
Set myPresentation = PowerPointApp.Presentations.Add
'Add a slide to the Presentation
Set mySlide = myPresentation.Slides.Add(1, 11)
'11 = ppLayoutTitleOnly
'Change Theme and Layout
mySlide.ApplyTheme "C:\Users\davinder.sond\AppData\Roaming\Microsoft\Templates\Document Themes\DefaultTheme.thmx"
myPresentation.PageSetup.SlideSize = 3
myPresentation.Slides(1).Shapes.Title.TextFrame.TextRange.Text = rng2
myPresentation.Slides(1).Shapes.Title.Left = 59
myPresentation.Slides(1).Shapes.Title.Top = 10
myPresentation.Slides(1).Shapes.Title.Height = 30
myPresentation.Slides(1).Shapes.Title.Width = 673
With myPresentation.Slides(1).Shapes.Title
With .TextFrame.TextRange.Font
.Size = 24
.Name = "Arial"
.Bold = True
.Color.RGB = RGB(255, 255, 255)
End With
End With
'Copy Excel Range
rng.Copy
'Paste to PowerPoint and position
mySlide.Shapes.PasteSpecial DataType:=2 '2 = ppPasteEnhancedMetafile
Set myShape = mySlide.Shapes(mySlide.Shapes.Count)
'Set position:
myShape.LockAspectRatio = 0
myShape.Left = 12
myShape.Top = 55
myShape.Height = 475
myShape.Width = 756
'Make PowerPoint Visible and Active
PowerPointApp.Visible = True
PowerPointApp.Activate
DateT = Format("h:mm:ss")
'Clear The Clipboard
Application.CutCopyMode = False
myPresentation.SaveAs "C:\Project Control CCJV\ExperimentsPunch\" & rng3 & ".pptm"
PowerPointApp.Quit
End Sub
You are creating a new presentation everytime you call Set myPresentation = PowerPointApp.Presentations.Add within ExcelRangeToPowerPoint().
You can either try to open/close the Presentation outside of ExcelRangeToPowerPoint() and add a parameter to the function like ExcelRangeToPowerPoint(myPresentationObject) then you can simple add the slides there
or
you call the function AddNumber() within ExcelRangeToPowerPoint() of coarse the you need to loop there...
e.g.
Sub ExcelRangeToPowerPoint()
' some preparative code
'Create a New Presentation
Set myPresentation = PowerPointApp.Presentations.Add
'Add a slide to the Presentation
Set mySlide = myPresentation.Slides.Add(1, 11)
For Each rng in rngSel.Areas
'Filling the presentation one slide at a time
AddSlide(rng)
Next
'Clear The Clipboard
Application.CutCopyMode = False
myPresentation.SaveAs "C:\Project Control CCJV\ExperimentsPunch\" & rng3 &
".pptm"
PowerPointApp.Quit
'some more code
End Sub
I have code in Outlook to export data, from emails in a selected folder, to an Excel Workbook.
In that workbook I have VBA code to parse the data (the subject line for now, eventually the body).
When I export from Outlook to a ".xlsx" file everything looks great.
When I export to my ".xlsm" file it adds columns with information that does not align with the correct imported information.
Ex: Column A & B are correct, A is the CreationTime, B is the full SubjectLine
Column C, D, E, etc. will be random parsed bits of subject lines.
Are the macros in the Excel workbook running when the export to Excel is happening?
If so, how can I prevent that?
My Outlook code:
Sub ExportToExcel()
On Error GoTo ErrHandler
Dim appExcel As Excel.Application
Dim wkb As Excel.Workbook
Dim wks As Excel.Worksheet
Dim rng As Excel.Range
Dim strSheet As String
Dim strPath As String
Dim intRowCounter As Integer
Dim intColumnCounter As Integer
Dim msg As Outlook.MailItem
Dim nms As Outlook.NameSpace
Dim fld As Outlook.MAPIFolder
Dim itm As Object
'Opens the Workbook and Sheet to paste in
strSheet = "Tester.xlsx"
strPath = "G:\Jason\"
strSheet = strPath & strSheet
Debug.Print strSheet
'Select export folder
Set nms = Application.GetNamespace("MAPI")
Set fld = nms.PickFolder
'Handle potential errors with Select Folder dialog box.
If fld Is Nothing Then
MsgBox "There are no mail messages to export", vbOKOnly, "Error"
Exit Sub
ElseIf fld.DefaultItemType <> olMailItem Then
MsgBox "There are no mail messages to export", vbOKOnly, "Error"
Exit Sub
ElseIf fld.Items.Count = 0 Then
MsgBox "There are no mail messages to export", vbOKOnly, "Error"
Exit Sub
End If
'Open and activate Excel workbook.
Set appExcel = CreateObject("Excel.Application")
appExcel.Workbooks.Open (strSheet)
Set wkb = appExcel.ActiveWorkbook
Set wks = wkb.Sheets(1)
wks.Activate
appExcel.Application.Visible = True
'Copy field items in mail folder.
For Each itm In fld.Items
intColumnCounter = 1
Set msg = itm
intRowCounter = intRowCounter + 1
Set rng = wks.Cells(intRowCounter, intColumnCounter)
rng.Value = msg.CreationTime
intColumnCounter = intColumnCounter + 1
Set rng = wks.Cells(intRowCounter, intColumnCounter)
rng.Value = msg.Subject
Next itm
Set appExcel = Nothing
Set wkb = Nothing
Set wks = Nothing
Set rng = Nothing
Set msg = Nothing
Set nms = Nothing
Set fld = Nothing
Set itm = Nothing
Exit Sub
ErrHandler:
If Err.Number <> 0 Then
MsgBox strSheet & " doesn't exist", vbOKOnly, "Error"
End If
Set appExcel = Nothing
Set wkb = Nothing
Set wks = Nothing
Set rng = Nothing
Set msg = Nothing
Set nms = Nothing
Set fld = Nothing
Set itm = Nothing
End Sub
Parsing code in Excel:
Sub SplitSubjectLine()
Dim text As String
Dim i As Integer
Dim y As Integer
Dim LastRow As Long
Dim name As Variant
ReDim name(3)
LastRow = Cells(Rows.Count, "A").End(xlUp).Row
For y = 1 To LastRow
Cells(y, 2).Select
text = ActiveCell.Value
name = Split(text, ",")
For i = 0 To UBound(name)
Cells(y, i + 2).Value = name(i)
Next i
Next
End Sub
You need to wrap your actions in Excel with :
appExcel.EnableEvents = False (before your actions in Excel) and
appExcel.EnableEvents = True when you are done in Excel
Pseudo code :
''Start of your sub
Set appExcel = CreateObject("Excel.Application")
appExcel.EnableEvents = False
''Your actions in Excel
appExcel.EnableEvents = True
''End of your sub
I have a word document which is updated periodically. I can go into that Word document, select the contents of an entire table and copy, then go into an Excel spreadsheet and paste it. It's screwed up; however, I fix it as follows:
sht.Cells.UnMerge
sht.Cells.ColumnWidth = 14
sht.Cells.RowHeight = 14
sht.Cells.Font.Size = 10
This manual copy-paste works regardless of whether the table is has merged fields.
Then I can start to manipulate it manually: parsing, checking, computations, etc.
I can do this one table at a time, but it's tedious and of course error prone.
I want to automate this. I found some code:
Sub read_word_document()
Dim sht As Worksheet
Dim WordDoc As Word.Document
Dim WordApp As Word.Application
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = False
On Error GoTo ErrHandler
Set WordDoc = WordApp.Documents.Open("Z:\mydir\myfile1.DOC", ReadOnly:=True)
j = 0
For i = 1 To WordDoc.Tables.Count
DoEvents
Dim s As String
s = WordDoc.Tables(i).Cell(1, 1).Range.Text
Debug.Print i, s
WordDoc.Tables(i).
Set sht = Sheets("temp")
'sht.Cells.Clear
sht.Cells(1, 1).Select
sht.PasteSpecial (xlPasteAll)
End If
Next i
WordDoc.Close
WordApp.Quit
GoTo done
ErrClose:
On Error Resume Next
ErrHandler:
Debug.Print Err.Description
On Error GoTo 0
done:
End Sub
Of course this would just overwrite the same sheet again and again - and that's okay. This is just a test. The problem is this will work for those tables that do not have merged cells. However, it fails if the table has merged cells. I have no control over the file I get. It contains almost a hundred tables. Is there a way to do the copy paste the EXACT WAY that I do when I perform the operation manually?
Something like this:
Sub read_word_document()
Const DOC_PATH As String = "Z:\mydir\myfile1.DOC"
Dim sht As Worksheet
Dim WordDoc As Word.Document
Dim WordApp As Word.Application
Dim i As Long, r As Long, c As Long
Dim rng As Range, t As Word.Table
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = False
Set WordDoc = WordApp.Documents.Open(DOC_PATH, ReadOnly:=True)
Set sht = Sheets("Temp")
Set rng = sht.Range("A1")
sht.Activate
For Each t In WordDoc.Tables
t.Range.Copy
rng.Select
rng.Parent.PasteSpecial Format:="Text", Link:=False, _
DisplayAsIcon:=False
With rng.Resize(t.Rows.Count, t.Columns.Count)
.Cells.UnMerge
.Cells.ColumnWidth = 14
.Cells.RowHeight = 14
.Cells.Font.Size = 10
End With
Set rng = rng.Offset(t.Rows.Count + 2, 0)
Next t
WordDoc.Close
WordApp.Quit
End Sub