VBA: xmlhttp response paste is sometimes omitting tabs? - excel

EDIT2: I can't find why it might be pasting it incorrectly but the responseText reads as tab every time and I can just split it into an array and avoid the clipboard altogether. I'd still appreciate if someone has any ideas as to why this might've happened.
Sub example()
Dim clip As Object, D As Object, H As Object, URL As String
Set clip = CreateObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
Set H = CreateObject("WinHTTP.WinHTTPRequest.5.1")
Set D = CreateObject("HTMLFile")
'authentication
'xmlrequest
'here
URL = "https:/someinternal.site/tsv?filter=querystring"
H.Open "GET", URL
H.send
clip.SetText H.responseText
clip.PutInClipboard
Sheet1.Range("A1").PasteSpecial
End Sub
I'm trying to query an internal site that responds with a .TSV and I'm getting inconsistent results. Sometimes it pastes in properly split into columns, other times it ommits all of the deliminators and drops it in like this:
FullNameFirstLast
John SmithJohnSmith
When it should be:
FullName First Last
John Smith John Smith
I've found resources where people talk about using the TextToColumns manually to set the default for the deliminator, but when I paste into Excel, it looks the same - all tabs are taken out. If I paste the website (just a raw .TSV) into notepad++ and from there into Excel, it properly shows the tabs and line breaks on the editor and works in Excel. If I debug.Print H.responseText, the response it gives me replaces all of the tabs with 4 spaces which I guess is pretty normal for the immediate window but it doesn't help me.
Elsewhere in the code, I also query a .CSV file using the same method which I think is breaking it. Are there any parameters I can set to properly parse the response, or another method to use? For this I could use a querytable connection, but due to the authentication that needs to happen first, this has its own problems and I try to avoid them like the plague.
EDIT: paste dump from Excel pasted as an image instead of text. Even more confusing is when I copy and paste the Excel output into notepad or notepad++, it properly displays the tabs. Pasting it back into Excel produces the same result. This means the response is coming out right, but Excel itself is doing something strange with the tabs... Manual TextToColumns worked when it wasn't finding the deliminator earlier. Sometimes it comes out as four spaces and other times, invisible tabs - this is the issue.

Related

How to copy text contained in a cell to clipboard

I'm very new to this, so please bear with me.
Background info: I'm trying to create my own quickparts / textblock tool so to speak.
In order to achieve this I have created multiple "buttons" that i want to assign to macros.
The desired result is, that you only have to click the button (named "holidays" for instance) and the corresponding explanatory text is copied into your clipboard.
The problem is that the corresponding text passages are often long and I don't want them included in the code as is the case at the moment where I use this:
Sub Holidays()
Dim obj As New DataObject
Dim txt As String
txt = "Holidays must be requested minimum 2 weeks prior"
obj.SetText txt
obj.PutInClipboard
Beep
End Sub
Instead of having the explanatory text in the code I would like to have it stored in a cell in a different sheet and it to be accessed and copied into the clipboard.
What I have tried so far is putting the text in a cell and named it [Holidays].
I can also set it as a message box, but can't seem to figure out how to get it into the clipboard.
Can anyone help me out with this?
Thanks a lot!

Copy arrays from different location in a worksheet and use it to paste it into any other application without additional spaces

My excel sheet creates three proper sentences at three different locations in the worksheet based on the data in the tables but has double spaces between some of the words. I am trying to find a code where I can click a button that copies information from these different arrays in the worksheet that I can then paste into a word file without any double spaces or tab spaces and add some additional generic lines.
Currently, we are manually copying information from these arrays into a notepad to remove the table, the cells and their formating. Then manually replace all the double space and tab spaces with a single space, add some additional generic lines and then copying this information into a Word file.
Trying to write a code that will allow me to do this by clicking the button and then pasting it anywhere I want. What code can I use for this? Thanks.
Here are some ideas, untested so you will probably have to experiment to get them to work. If you get stuck, please use google to research the problem, then post your code and issue in a new question, so folk have more to go on. I'm assuming you have found the VBA editor, the alt-f11 shortcut may work.
Use the Names Manager to designate each of the three sentence locations as a "named range", e.g. first_sentence, second_sentence and third_sentence
Choose a shape and add it to your workbook. The shape will serve as the button. If you right click on the shape, at the bottom of the list of options, is one to connect a macro (which does not exist yet)
In the VBA code editor, make a new module, then create the macro by typing what is below. After creating it, you can connect it to your button, and that will allow you to test it.
Option explicit
' the macro "transfer_text" controls the export of text from the Excel sheet to the Word document
sub transfer_text()
' this is where clean-up code and everything goes
end sub
You need to tell your transfer_text macro where the cells of interest are, perhaps by pasting the following into the body of the macro:
dim range_first as range, range_second as range, range_third as range, clean_first as string, clean_second as string, clean_third as string
' set the ranges so the macro knows where the data is
with thisworkbook.worksheets("Sheet1")
set range_first = .range("first_sentence")
set range_second = .range("second_sentence")
set range_third = .range("third_sentence")
end with
' update the data (without changing the original) using the clean_text function (see below)
clean_first = clean_text(range_first)
clean_second = clean_text(range_second)
clean_third = clean_text(range_third)
' this is where we connect Word
I would use a function to clean the text in each of the ranges, like this, stored outside the main macro, though in the same module for convenience. You can add text editing operations to it later:
Function clean_text(string_text as string) as string
' the text from the range is passed in
' various operations performed on the text
' the result is sent back to where the function was called
clean_text = trim(string_text)
end function
That is rather alot already, and we have not even connected to Word. To connect to Word is really better done as a separate topic. You will need to set a specific reference to word, using the Tools-References menu in the VBA project. Scroll down the list until you find Microsoft Word, and tick the box.
That will give you access to the object library for Word, so you can place your text using bookmarks in the Word document.
You will also need to deal with the file object - opening the Word document. Another topic for you to research!
That should get you started!
Some notes on debugging. Set a breakpoint at the start of the With statement by clicking the mouse in the left hand margin of the code editor. Then click you button... the code will stop at the breakpoint. Use the mouse-over and the Immediate Window (you may need to unhide it) to check variable values. Press F8 to step forward one line of code. In the Immediate Window, type a ? followed by the variable you want to check.

Excel VBA code that Copy/Pastes into a word document is causing my code to fail

I have an excel sheet
Which is generating a word document (which then gets converted into PDF)
The code loops through various rows of data and creates a page in word based on the data
Part of the loop takes a Graph from Excel and pastes it into the word page.
The code all works fine, and it generates the word document the way I want it. But the copy/paste of the chart is causing me intermittent issues.
The strange behaviour is that :
1 - My code will suddenly exit before it's finished looping through the data.
2 - I can't step through the code using F8 in break mode, as soon as I get to the code that does the pasting, the code just runs everything.
3 - if I put a break point just after the paste, and let the code stop and press f5 continuously, then I don't get the code suddenly exiting.
(Sorry it's such a long explanation)
This is a snippet of my code where the problem is occuring
IndividualChartSheet.ChartObjects("IndividualCompletionChart").Copy
DoEvents
objRange.PasteSpecial Link:=False, DataType:=wdPasteMetafilePicture, Placement:=wdWrapSquare, DisplayAsIcon:=False
Application.CutCopyMode = False
DoEvents
Set myShape = objDoc.InlineShapes.Item(objDoc.InlineShapes.Count).ConvertToShape
myShape.WrapFormat.Type = wdWrapBehind
myShape.RelativeVerticalPosition = wdRelativeVerticalPositionPage
myShape.Top = InchesToPoints(2)
myShape.Left = InchesToPoints(-0.4)
objRange is a reference to a range in my word object.
I can get the code to run, by putting a breakpoint on the Application.CutCopyMode = False and then pressing F5. But I'm hoping to pass this tool on to other users, so I can't need to fix this.
I added in the DoEvents and the CutCopyMode = False after some searching.
I also tried moving the paste command into a seperate function.
But that didn't work.
In case anyone is interested I finally go to the bottom of it.
Such a weird one that it took me a really long time to figure out.
Basically part of my code that was constructing the word document was also adding in hyperlinks so the the person looking at my final output (word document converted to a pdf file) could jump around the document.
My hyperlinks and bookmarks were based on employee names and word didn't like me having non alphanumeric characters in the hyperlink/bookmark names. Once I removed those the code runs through without any problems now.

How to position a chart copied from excel into powerpoint using CommandBars?

I am trying to copy some charts (embedded) in different worksheets of an excel workbook using vbscript into different slides of a powerpoint. I would like to keep the link between the excel sheet and the powerpoint while doing so and therefore I used the below piece of code that allows me to keep formatting and link (instead of a simple paste or PasteSpeical. Is there any other way?) :
For i = 1 to TotalNumWorkSheets 'I iterated with indices.
Set pptSlide = pptPres.Slides.Add(i, 11) 'There is one opening slide before this.
set ws = wb.Worksheets(i)
ws.ChartObjects(1).Chart.ChartArea.Copy
pptApp.CommandBars.ExecuteMso("PasteExcelChartSourceFormatting")
pptApp.CommandBars.ReleaseFocus
With pptSlide
.Shapes.Title.TextFrame.TextRange.Text = objCurSheet.Name
'Adding some more textboxes here. Working fine. Position checks out in PPT.
.Shapes(.Shapes.Count).Left = 20 'Doesn't work for all slides.
End With
Next
The code works and copies all the charts, creates titles, adds new text as expected, but I am not able to position the charts on individual slides because after the ExecuteMso command, I don't know how to access the reference to the chart. I read in one of the SO posts that pasting using this method looses the chart selection but you can access the last .Shapes object since pasting always adds the object to the end of the list. Is that always the case? I tried accessing and positioning my chart by accessing the last object but it only works for the first slide of the loop (i.e. the first chart pasted is shifted to Left=20). The rest all charts in other slides are centered. Can someone explain where and how to add the formatting chart options? I ran into an even weirder problem. If I increase the number of worksheets, even the first plot looses it's Left formatting. The above code is the only place where I add formatting so I don't know what is happening. I am sure I am not formatting it correctly.
Many thanks for your suggestions.
Edit: One additional thing which I tested. I am using
WScript.Sleep 500
code before the For loop ends since it gives enough time for earlier operations to finish (at least that's what I understood from many other google searches).
So after some more searching and testing, I found a solution (for my case at least).
Moved the WScript.Sleep 1000 (500 didn't work for me) statement just below CommandBars.ReleaseFocus.
It makes some sense now since it is the Chart copying, pasting and linking from excel that needs time. Especially with source formatting. After that there is only text generation which I believe is not so heavy.
Cleared all the set Object variables when not used. Especially the ones associated with the "With" keyword.
set obj = CreateObject()
With obj
'Do something here.
End With
set obj = Nothing
Not clearing them, apparently, can also prevent you from closing the applications even after you use the .Close and .Quit method. At least that's what I observed. I found PowerPoint.exe running in the task manager when nothing was opened.
After doing the above, I am able to copy with format the charts and also able to set the position of the charts. The weird problem of larger number of worksheets also disappeared. Hopefully, it might help others. If someone thinks the observations are incorrect or troublesome, please correct.

Replacing text in an email with a picture from the clipboard

I have a report that I send out daily.
In it there is a linked image to a range that I need to paste into an email and send.
I have the email saved as an outlook template file that I modify as necessary when I need to.
The code I have runs from Excel.
I create an Outlook object and open the Outlook email from the .oft template file, then I want to find the identifier text (INSERT IMAGE HERE) and replace it with the linked image from Excel, which has been copied from the clipboard.
I am trying to add it as an InLineShape so that it behaves properly in the body of the email.
I have been attempting to do it with a defined WordEditor from the body of the email.
I looked into HTML to do it, but I decided the WordEditor object would be a better approach.
After I paste it, I need to set the scale height to 0.75 so that it is displayed properly.
From there, just click send.
Here is a quick sample of my code:
Set OutlookApp = CreateObject("Outlook.Application")
Set OutlookEmail = OutlookApp.CreateItemFromTemplate(templatePath)
OutlookEmail.Display 'Just for code checking
ThisWorkbook.Worksheets("Email Sheet").Pictures("Summary Email Screenshot").Copy
Set EmailText = OutlookEmail.GetInspector.WordEditor
With EmailText.Range.Find
.ClearFormatting
.Execute findText:="*INSERT IMAGE HERE*", MatchWholeWord:=True, MatchCase:=True, _
MatchWildcards:=False, ReplaceWith:="^c", Replace:=wdReplaceOne
End With
EmailText.InlineShapes(EmailText.InlineShapes.count).ScaleHeight = 75
'OutlookEmail.Send
The problem arises with that last line before I send it.
What happens is it is not inserted as an InLineShape, but just a shape so that it floats on top of the text.
I need it as an InLineShape so that the content after the image moves down and is displayed rather than being covered by it.
I've been scowering forums for a while to try to find an answer but to no avail.
I am pretty well versed in Excel VBA, but this is my first attempt at Outlook and Word VBA so please, bear with me.
By default when an image is pasted Word will use the setting Insert/paste pictures as from File/Options/Advanced, section "Cut, copy and paste". So on some machines an image might be pasted as an InlineShape and on others as a Shape.
If you were simply pasting in the code then using PasteSpecial it would be possible to specify inline or with text wrap using the corresponding WdOLEPlacement enumeration value of either wdFloatOverText or wdInLine.
Since the paste command is coming from the ^c replacement text this approach won't work for this situation. That means the Options setting will need to be changed. And, in order for this to be user-friendly, at the end of the code it should be changed back.
Here's some sample code demonstrating how to check the current option, change it if necessary, and reset at the end of the procedure. I'm not familiar with using Word through the Outlook object model, but I think I've correctly instantiated an object for the Word.Application so that VBA executing in Excel or Outlook will know what Options are meant. Except for the last line, this should come between Set and With in the code sample in the question.
Dim wrapType As Long
Dim wordApp as Object
Set wordApp = EMailText.Application
wrapType = wordApp.Options.PictureWrapType
If wrapType <> wdWrapMergeInline Then
wordApp.Options.PictureWrapType = wdWrapMergeInline
End If
'Do other things, then reset
wordApp.Options.PictureWrapType = wrapType

Resources