VBA in Excel - Pasting to Active Cell then Tab Right - excel

I am needing a bit of assistance with Excel VBA. I am switching back and forth from Excel and another application and copying, pasting into Excel from the other application. I already have that process down, but I am needing advice on how I can paste into whatever cell is currently active, tab right, and at the end of that row go down one row, then start back in column D. Actually, here is a list of the exact process I am needing to happen inside the Excel application:
[Number Format] Paste into currently active cell (will always be in the D:D column)
Tab right one cell
[Date Format: "d-mmm"] Today's Date
Tab Right
[Text] Paste
Tab Right
[Accounting] Paste
Tab Right
Type the letter "X" in that column
Enter down one line, starting back in the D column.
Between all of these steps I have the majority of that code figured out that interacts with the other application. But I do have one question in regards to that as well -- In that application I am running this statement:
With ATC.ActiveSession (ATC is simply referencing the application's type library to interact with other application)
As opposed to me ending the With statement every time the applications switch back and forth copying and pasting, what would I need to do use as a with statement to use excel's library?
Example of what I don't want to happen:
Sub New_ATS()
Set ATC = GetObject(, "ATWin32.AccuTerm")
AppActivate "AccuTerm 2K2"
With ATC.ActiveSession
.InputMode = 1
.SetSelection 6, 15, 12, 15
.Copy
.InputMode = 0
End With
AppActivate "Microsoft Excel"
Selection.Paste '(not complete, part of question)
Selection.Offset 1, 0 'again, part of the question
AppActivate "AccuTerm 2K2"
With ATC.ActiveSession
.InputMode = 1
.SetSelection 14, 3, 20, 3
.Copy
.InputMode = 0
End With
AppActivate "Microsoft Excel"
' .... end of partial code (continues on)
End Sub
But instead, would like to 'chain' the With statements, but I don't know what statement I would use to point back to Excel's VBA. This is what I would like:
Sub New_ATS()
Set ATC = GetObject(, "ATWin32.AccuTerm")
AppActivate "AccuTerm 2K2"
With ATC.ActiveSession
.InputMode = 1
.SetSelection 6, 15, 12, 15
.Copy
.InputMode = 0
With Excels_Statement '?????
AppActivate "Microsoft Excel"
Selection.Paste '(not complete, part of question)
Selection.Offset 1, 0 'again, part of the question
AppActivate "AccuTerm 2K2"
With ATC.ActiveSession
.InputMode = 1
.SetSelection 14, 3, 20, 3
.Copy
.InputMode = 0
With Excels_Statement '????
AppActivate "Microsoft Excel"
End With
End With
End With
End With
' .... end of partial code (continues on)
End Sub

I don't have AccuTerm installed but I think you can paste into Excel without having to activate it each time. Instead of using With blocks, you could assign an object variable with minimal typing... not the best practice for variable naming but it would do the trick. Declaring the variable of the specific type would give you access to Excel's library.
Here's what I'm thinking... (partially tested so you might have to tweak it a little)
Sub New_ATS()
Set ATC = GetObject(, "ATWin32.AccuTerm")
Dim Sesh as ATWin32.AccuTerm.Session 'Not sure this exists
Dim XL as Excel.Range
AppActivate "AccuTerm 2K2"
Set Sesh = ATC.ActiveSession
Sesh.InputMode = 1
Sesh.SetSelection 6, 15, 12, 15
Sesh.Copy
Sesh.InputMode = 0
'AppActivate "Microsoft Excel" - don't need it
Set XL = application.activecell
XL.PasteSpecial
Set XL = XL.offset(0,1)
'AppActivate "AccuTerm 2K2" - no need, still active
Sesh.InputMode = 1 'Once this is set, do you need to set it again?
Sesh.SetSelection 14, 3, 20, 3
Sesh.Copy
Sesh.InputMode = 0 'Once this is set, do you need to set it again?
XL.PasteSpecial
XL.NumberFormat = "General" 'Bullet #1
Set XL = XL.offset(1,0)
'...and so on...
XL.PasteSpecial
XL.NumberFormat = "d-mmm" 'Bullet #3
Set XL = XL.offset(1,0)
XL.PasteSpecial
XL.NumberFormat = "#" 'Bullet #5
Set XL = XL.offset(1,0)
XL.PasteSpecial
XL.NumberFormat = "_($* #,##0.00_);_($* (#,##0.00);_($* "-"??_);_(#_)" 'Bullet #7
Set XL = XL.offset(1,0)
XL = "X" 'Bullet #9
'When you've reached the end of the row
Set XL = XL.offset(1, 4 - XL.Column) 'Since col D = 4
'And repeat your procedure
End Sub

Related

Insert text at specific place in the document

When I insert the data into Bookmark, it goes to the beginning of the line.
What a property needs to be set to insert the text in the middle of the paragraph?
Data is copied from Excel
Tried so far:
Copy range and paste
Copy text from value and pastespecial
Paste is floating everywhere, but not at Bookmark.
If wDoc.Bookmarks.Count = 0 Then GoTo BookmarkMissing
For i = 1 To wDoc.Bookmarks.Count
If wDoc.Bookmarks(i).Name = sBookmarkName Then
Set wdRange = wDoc.Bookmarks(i).Range
Let bBookmarkFound = True
End If
Next i
If Not bBookmarkFound Then GoTo BookmarkMissing
Else
Set wdRange = wDoc.Range
End If
MyData.SetText rngToSend.Value2
MyData.PutInClipboard
On Error Resume Next
On Error GoTo 0
'rngToSend.Copy
'wdRange.PasteSpecial Placement:=wdFloatOverText, DataType:=2
wdRange.InsertAfter
wdRange.Tables(1).ConvertToText Separator:=" "
'wdRange.PasteSpecial Placement:=wdFloatOverText, DataType:=2
'wdRange.PasteSpecial Placement:=wdInLine
Your code can be greatly simplified. There is no need to loop through bookmarks to find if the one you need exists as the object model has a method to do that.
So this code:
If wdoc.Bookmarks.Count = 0 Then GoTo BookmarkMissing
For I = 1 To wdoc.Bookmarks.Count
If wdoc.Bookmarks(I).name = sBookmarkName Then
Set wdRange = wdoc.Bookmarks(I).Range
Let bBookmarkFound = True
End If
Next I
If Not bBookmarkFound Then GoTo BookmarkMissing
Can be replaced with this
If wdoc.Bookmarks.Exists(sBookmarkName) Then
wdoc.Bookmarks(sBookmarkName).Range.text = rngToSend.Value2
Else
GoTo BookmarkMissing
End If
Since you're moving plain text, the clipboard is not necessary.
wDoc.Bookmarks(i).Range.Text = rngToSend.Value2
Thank you guys for your help. However, I had a bug, one old line of code (not visible in my post_ was still pasting value as a Excel range and inserting a table instead of text.
So now is solved

Checking Threaded Comments

My office just upgraded to a new version of Office 365, and with it came a new way that comments are done. The old comments are now referred to as "notes" and the new comments are now called "comments".
In one of my workbooks, I have a button that, when clicked, will look through certain cells to check whether there is a comment or not. It will then color the cell based on what it finds.
(my full code for the button is posted below)
Line 9 contains the issue
In previous versions of Excel, this button worked just fine. However, now it only works if the cells have "notes" and does not work if they have "comments". In my code, the class that I had been using was called "Comment", so my code was something along the lines of "If Cells(row, col).Comment Is Nothing...". This class still works, but only looks for notes. I have looked through the Object Library and under the hidden objects, I found a new class called "CommentThreaded". I tried changing my code to that ("If Cells(row, col).CommentThreaded Is Nothing...") but it does not work. When I click the button, I now get a run-time error: applictaion-defined or object-defined error when it tries to access this new class.
Does anyone know what I need to change to get my button to work with threaded comments?
Thanks,
Mike
Sub Comments()
Dim xrow As Integer
Dim xcol As Integer
For xrow = 7 To 88
For xcol = 3 To 15
If Cells(xrow, xcol).Value <= -0.1 Or Cells(xrow, xcol).Value >= 0.1 Then
If Cells(5, xcol).Value = "MTD %" Or Cells(5, xcol).Value = "YTD %" Then
If Not Cells(xrow, xcol).Comment Is Nothing Then
Cells(xrow, xcol).Interior.Color = RGB(155, 255, 188)
Else
Cells(xrow, xcol).Interior.Color = RGB(255, 255, 0)
End If
End If
End If
Next xcol
Next xrow
End Sub
As of May 15th 2019 the new object CommentThreaded is described by Microsoft.
In my Excel version 1906, it's fully supported in VBA.
Your assumed If Range.CommentThreaded Is Nothing works.
Here's some code to play with:
Private Sub ExcelsNewCommentThreaded()
Dim AllCommentsThreaded As Excel.CommentsThreaded
Dim OneCommentThreaded As Excel.CommentThreaded
Dim AllReplies As Excel.CommentsThreaded
Dim OneReply As Excel.CommentThreaded
Dim r As Range
Set AllCommentsThreaded = ActiveSheet.CommentsThreaded
' loop over all threaded comments of a worksheet and get their info
For Each OneCommentThreaded In AllCommentsThreaded
With OneCommentThreaded
Debug.Print .Author.Name, .Date, .Text
For Each OneReply In .Replies
With OneReply
Debug.Print .Author.Name, .Date, OneReply.Text
End With
Next OneReply
End With
Next OneCommentThreaded
Set r = Selection.Cells(1)
' check if the selected cell already contains a threaded comment
If r.CommentThreaded Is Nothing Then
r.AddCommentThreaded ("my new comment")
End If
With r.CommentThreaded
' get text of comment
Debug.Print .Text
' add some replies
.AddReply ("my reply 1")
.AddReply ("my reply 2")
' change text of comment
Debug.Print .Text(Text:="text of comment changed")
Debug.Print .Text
' change text of a reply
.Replies(1).Text Text:="text of reply 1 changed"
Debug.Print .Replies(1).Text
' delete second reply
.Replies(2).Delete
' delete whole comment including its replies
.Delete
End With
End Sub

Excel VBA to Create PowerPoint Presentation

Looking for some help on updating a VBA Script that completes the following (basic algorithm):
Excel Template with formulas and macros creates a custom report consisting of approximately 30 charts
Macro called “CreatePowerPointPresentation” is used to transfer these charts into a specific PowerPoint template in specific format
The macros uses the slides contained in the template to create the first 6 slides
The macro then adds slides (transitions and content slides)
Note: This macro was actually created based on a feedback from this forum
This macro works great in Windows 7 with Office 2013, but generates errors in Windows 10, Office 2016 after slide 8 is created, randomly during one of the paste chart actions, but never gets past slide 10 of a 17-slide deck.
Errors:
Runtime Error '-2147188160 (80048240)
Method 'PasteSpecial'of object 'Shapes' failed.
Or
Runtime Error '-2147023170 (800706be)':
Automation Error
The Remote procedure call failed.
I'm not sure if this is an object issue or some other piece that I'm missing.
Code below:
Sub CreatePowerPointPresentation()
'=========================================================================
'Create PowerPoint Presentation
'Assigned to Index Tab
'==========================================================================
Dim newPowerPoint As PowerPoint.Application
Dim activeSlide As PowerPoint.Slide
Dim CHT As Excel.ChartObject
Dim fmt As String
Dim hgt As String
Dim wth As String
‘this code allows for the user to select whether to paste the charts as Excel Charts or PNG Formatted images.
Sheets("Index").Select
If Range("AB7").Value = "Excel Charts" Then
fmt = ppPasteDefault
Else
fmt = ppPastePNG
End If
'Establishes the global height and width of the graphics or charts pasted from Excel
hgt = 280
wth = 710
'Look for existing instance
On Error Resume Next
Set newPowerPoint = GetObject(, "PowerPoint.Application")
On Error GoTo 0
'Create a new PowerPoint
If newPowerPoint Is Nothing Then
Set newPowerPoint = New PowerPoint.Application
End If
'Make a presentation in PowerPoint
If newPowerPoint.Presentations.Count = 0 Then
newPowerPoint.Presentations.Add
End If
'Show the PowerPoint
newPowerPoint.Visible = True
Application.EnableEvents = True
Application.ScreenUpdating = True
'Apply Template & Create Title Slide 1
newPowerPoint.ActivePresentation.ApplyTemplate Application.DefaultFilePath & "\file.potx"
'Set presentation to be 16x9
'AppActivate ("Microsoft PowerPoint")
With newPowerPoint.ActivePresentation.PageSetup
.SlideSize = ppSlideSizeOnScreen16x9
.FirstSlideNumber = 1
.SlideOrientation = msoOrientationHorizontal
.NotesOrientation = msoOrientationVertical
End With
'Create Slides 2-6 these are imported from the template
newPowerPoint.ActivePresentation.Slides.InsertFromFile Application.DefaultFilePath & "\File.potx", 0, 1
'Create Slide 7
newPowerPoint.ActivePresentation.Slides.Add newPowerPoint.ActivePresentation.Slides.Count + 1, ppLayoutBlank
newPowerPoint.ActivePresentation.Slides(7).CustomLayout = newPowerPoint.ActivePresentation.SlideMaster.CustomLayouts(33)
Set activeSlide = newPowerPoint.ActivePresentation.Slides(newPowerPoint.ActivePresentation.Slides.Count)
With newPowerPoint.ActivePresentation.Slides(7)
.Shapes("Title 1").TextFrame.TextRange.Text = "Title1"
End With
newPowerPoint.ActiveWindow.ViewType = ppViewSlide
‘Create Slide 8 – Quad Chart Slide
newPowerPoint.ActivePresentation.Slides.Add newPowerPoint.ActivePresentation.Slides.Count + 1, ppLayoutBlank
newPowerPoint.ActivePresentation.Slides(8).CustomLayout = newPowerPoint.ActivePresentation.SlideMaster.CustomLayouts(13)
newPowerPoint.ActiveWindow.View.GotoSlide newPowerPoint.ActivePresentation.Slides.Count
newPowerPoint.ActivePresentation.Slides(8).Shapes("Title 1").TextFrame.TextRange.Text = "Title 1"
Set activeSlide = newPowerPoint.ActivePresentation.Slides(newPowerPoint.ActivePresentation.Slides.Count)
newPowerPoint.ActiveWindow.ViewType = ppViewSlide
'Upper Left
Sheets("Charts").Select
ActiveSheet.ChartObjects("Chart 3").Select
ActiveChart.ChartArea.Copy
newPowerPoint.ActiveWindow.ViewType = ppViewSlide
activeSlide.Shapes.PasteSpecial(DataType:=fmt).Select
'Adjust the positioning of the Chart on Powerpoint Slide
newPowerPoint.ActiveWindow.Selection.ShapeRange.Left = 5
newPowerPoint.ActiveWindow.Selection.ShapeRange.Top = 75
newPowerPoint.ActiveWindow.Selection.ShapeRange.LockAspectRatio = msoFalse
newPowerPoint.ActiveWindow.Selection.ShapeRange.Height = 145
newPowerPoint.ActiveWindow.Selection.ShapeRange.Width = 345
'Upper Right
Sheets("Charts").Select
ActiveSheet.ChartObjects("Chart 2").Select
ActiveChart.ChartArea.Copy
newPowerPoint.ActiveWindow.ViewType = ppViewSlide
activeSlide.Shapes.PasteSpecial(DataType:=fmt).Select
newPowerPoint.ActiveWindow.Selection.ShapeRange.Left = 350
newPowerPoint.ActiveWindow.Selection.ShapeRange.Top = 75
newPowerPoint.ActiveWindow.Selection.ShapeRange.LockAspectRatio = msoFalse
newPowerPoint.ActiveWindow.Selection.ShapeRange.Height = 145
newPowerPoint.ActiveWindow.Selection.ShapeRange.Width = 345
'Lower Left
Sheets("Charts").Select
ActiveSheet.ChartObjects("Chart 4").Select
ActiveChart.ChartArea.Copy
newPowerPoint.ActiveWindow.ViewType = ppViewSlide
activeSlide.Shapes.PasteSpecial(DataType:=fmt).Select
newPowerPoint.ActiveWindow.Selection.ShapeRange.Left = 5
newPowerPoint.ActiveWindow.Selection.ShapeRange.Top = 230
newPowerPoint.ActiveWindow.Selection.ShapeRange.LockAspectRatio = msoFalse
newPowerPoint.ActiveWindow.Selection.ShapeRange.Height = 145
newPowerPoint.ActiveWindow.Selection.ShapeRange.Width = 690
‘More slides……
Application.EnableEvents = True
Application.ScreenUpdating = True
Set activeSlide = Nothing
Set newPowerPoint = Nothing
End Sub
This sounds like the dreaded code-runaway scenario I have faced in PowerPoint before where it takes more time to copy things to and paste things from the Windows clipboard than the VBA code execution and hence the VBA code runs ahead and fails as a result. To confirm that this is the cause, put some break points on the .Copy, .ViewType and .PasteSpecial lines and see if it still fails for your full slide collection. If not, try adding some DoEvents lines after the .Copy and .ViewType lines and if that doesn't help, inject a Delay of one or two seconds instead of the DoEvents. That will at least confirm if the hypothesis is true or not.

VBA Option Button does not get centered

I have a worksheet that has two rows of option buttons. Option buttons 1 - 11 are on row 7 and option buttons 12 - 22 are on row 9 of the sheet. My code loops through and centers each option button in its appropriate cell by calling the centerOfCell function.
When I run my program Worksheets("Orders") gets passed into the CenterOptionButton procedure, and all of the option buttons get centered EXCEPT for option button 1. I cannot figure out why this happens.
Sub CenterOptionButton(wks As Worksheet)
Dim i As Byte
With wks
Select Case .Name
Case "RDC", "SKU"
optionCount = 8
Case "Orders"
optionCount = 11
Case Else
End Select
For i = 1 To optionCount
.OLEObjects("OptionButton" & i).Left = centerOfCell(.Cells(7, i + 1))
.OLEObjects("OptionButton" & i + optionCount).Left = centerOfCell(.Cells(9, i + 1))
Next i
End With
End Sub
If I then run the below procedure all by itself substituting out wks with Worksheets("Orders"), everything works perfectly. Any idea on what the issue could be?
Sub test()
Dim i As Byte
With Worksheets("Orders")
Select Case .Name
Case "RDC", "SKU"
optionCount = 8
Case "Orders"
optionCount = 11
Case Else
End Select
For i = 1 To optionCount
.OLEObjects("OptionButton" & i).Left = centerOfCell(.Cells(7, i + 1))
.OLEObjects("OptionButton" & i + optionCount).Left = centerOfCell(.Cells(9, i + 1))
Next i
End With
End Sub
Try to copy the other option button and replace the first option button. The issue might get resolved. As for why it is happening I would not know. Excel has been know to through up unknown errors. I would normally recreate the file or object and the issue is usually solved.

Excel VBA to Internet Explorer - select all doesn't work on a pdf

The code below is my problem. It is meant to copy fund information from a website into a spreadsheet. It worked fine when the funds were on a non-pdf website but it doesn't work for pdf websites. It's the Select-All (ie2.ExecWB 17, 0) that fails and I can't crack it. If I do keyboard ctrl-A on the pdf website it selects all and a sendkeys version kind of half works but what I need is a solution to getting this "ie2.ExecWB 17, 0" to do what it is supposed to do.
any help greatly appreciated.
cheers
Sub ListFunds()
Dim DataObj As New MSForms.DataObject
Dim S As String
Dim ie1, ie2
Set ie1 = CreateObject("internetexplorer.application")
Set ie2 = CreateObject("internetexplorer.application")
HWNDSrc = ie2.HWND
ie1.Visible = True
ie2.Visible = True
ie1.navigate "http://www.legalandgeneral.com/workplacebenefits/employees/help-support/fund-zone/fund-factsheets/wpp-tbop-pptip.html"
Do Until ie1.readystate = 4
DoEvents
Loop
Dim LinkFound As Boolean
Dim linkCollection
Set linkCollection = ie1.document.all.tags("A")
For Each link In linkCollection
If InStr(1, link.outerhtml, "fundslibrary") <> 0 Then
ie2.navigate link
Do Until ie2.readystate = 4
DoEvents
Loop
ie2.ExecWB 17, 0 '// SelectAll
ie2.ExecWB 12, 2 '// Copy selection
DataObj.GetFromClipboard
S = DataObj.GetText
Selection.Value = S
Selection.Offset(1, 0).Select
End If
Next link
ie1.Quit
ie2.Quit
End Sub
Check this out, this might help you:
http://www.xtremevbtalk.com/showthread.php?t=299104
I'm not crazy about SendKeys at all, but I can't think of another way to capture the data from a PDF through a browser.

Resources