Collecting more than one data from Clipboard - excel

I manually copy 4 or 5 pieces of text from an email body to clipboard.
Then I want a procedure that assigns each one of these piece of text to a string variable separated by semicolons.
The “codes” below do not work. I write them just to helping explain what I want.
I will appreciate any help.
Sub ColectClipboardItems()
Dim strClip As String
strClip = vbNullString
For Each Item In Clipboard.Items
strClip = strClip & ";" & Item
Next Item
End Sub

I'm not sure if it's true, but the following link indicates that currently Excel can only handle information from the Windows clipboard, which only stores one value at a time:
Access The Nth Item of Clipboard
However, you could try to create the following:
Two step manual process:
A macro in Outlook that stores your data in the Windows clipboard (concatenated). Instead of Ctrl + C you would click a button in your Outlook ribbon.
A macro in Excel that retrieves such data from it.
I think this is prone to human errors.
Or a one step process:
A macro in Outlook that stores all your data & by itself calls another macro in Excel to save it there.
This depends on your e-mail having a consistent structure, though.

Related

Excel VBA / SAP GUI: how to get Value from Cell in SAP to Excel. "Node?"

I have created an Excel VBA Macro to connect to SAP GUI, pull data, etc. Nearly everything works, but I have one problem.
I am using the Transaction CV04N to download some documents from it. My code pastes all required Document names (or numbers) into the multiple selection here:
After executing it, we get this list:
Now my code just double clicks the list one-by-one and this opens up:
So, in most cases, there is only one PDF file in here, but sometimes there is also a TIFF file in there, which then produces an error, because the program tries to download it as a .pdf.
However I only want the PDF. But my program always just selects the first entry.
So I need a function/routine that reads what is in the first line, if it is not PDF, then take the next one. (there are never 2 PDFs in there, so taking the first PDF that shows up is sufficient)
If I just choose document, that only contain PDFs, then everything runs normal.
My current code looks like this (starts from the window shown in last picture)
For j = 0 To k - 1
On Error Resume Next
FileName = XYZ
SaveName = DlFolder & FileName
Session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").currentCellRow = j
Session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").doubleClickCurrentCell
Set Tree = Session.findById("wnd[0]/usr/tabsTAB_MAIN/tabpTSMAIN/ssubSCR_MAIN:SAPLCV110:0102/cntlCTL_FILES1/shellcont/shell/shellcont[1]/shell")
Tree.selectNode " 1"
Tree.nodeContextMenu " 1"
Tree.selectContextMenuItem "CF_EXP_COPY"
'It has selected the "copy to" in context menu, now just saves it to Folder saved in "Savename"
Session.findById("wnd[1]/usr/ctxtDRAW-FILEP").Text = SaveName
Session.findById("wnd[1]/tbar[0]/btn[0]").press
'goes to next doc:
Session.findById("wnd[0]/tbar[0]/btn[3]").press
Next
So, if I could get the data from the Table, I could select the one with TIFF, for that I need to read the table.
I have tried
Tree.Text
Tree.Value
Tree.Copy (and then paste in Excel)
But nothing gives me the correct value...
When I select the entry, and press CTRL-C and paste it somewhere it gives me the whole line, so a String with all columns in this entry.
If you have a solution just to get that mentioned String into a Excel Cell, that's fine with me! From there I can set up some routine to make it work.
I hope I made it understandable what I want, if not please feel free to reach out to me!

Excel macro to simply type predefined text into the active cell, as plain text

Very rudimentary: I wish to press F1 (Windows OS) to print, i.e., "XZ" in the active Excel cell (as plain/unformatted text), but in such a way that I can then enter "123" immediately thereafter, hence resulting in a cell value of XZ123.
This .xls is shared by other users, four of whom are in the document adding data at any given time. We save this to a Sharepoint folder, but nobody on the team ever accesses the document via the web version of Excel. We instead just double-click the document, at which point Excel boots up from our local hard drive, but when the document loads, we can see other users' active cell(s) based on highlights around the cells with their initials.
My hope is that this silly two-letter automation can be triggered only from my computer, and not embedded in the document file itself.
Huge thanks in advance for any guidance! This seems crazy simple but I honestly can't figure out how to do it. Cheers!
Unfortunately the only way for vba to enter edit mode is to use SendKeys
You'll need to use OnKey to map the function to F1
Const StringToEnter As String = "XZ"
Sub EnterValue()
Application.SendKeys "{F2}" & StringToEnter
End Sub
' Run this once to map F1 key. Maybe call from the `Workbook_Open` event
Sub SetupMappingToF1()
Application.OnKey "{F1}", "EnterValue"
End Sub

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.

Waiting for user input - with DoEvents a good idea?

My macro is going to compare a sheet with another sheet. This second sheet needs the user to paste data in there. (Note: The data being copied is not in Excel).
One way is to run the macro, and end it by prompting the user to paste the data in, then run "Macro2". However, I'd like to keep it all in one macro, so have found a way to wait for user input before continuing. This seems to work for me, so my main question is:
How stable is doing it this way?
...macro stuff above here
MsgBox ("[Please copy the data into the new sheet, after clicking 'OK']")
Do While WorksheetFunction.CountA(newWS.Cells(1, 7)) < 1
DoEvents
Loop
...then after the user pastes info, continue on, using the data that's been pasted.
The idea is that DoEvents just runs and runs while my sheet is blank. Right after the user pastes the data into the newWS, the macro continues on (since it will see data in column 7)...
Is this an okay method, or is it a bad idea to use like that? I've never really used DoEvents, so don't know if it's doing something in the background that could cause issues.
Edit: The data is in Lotus Notes, which I can export to Excel. However, that takes a few more steps (and I'd rather not create some new temporary excel files), so copy/pasting is my preferred method. This question is half practical, and half theoretical. Sorry for any confusion!
Probably not the best idea. Instead, allow them to select the data and perform the copy, all through VBA:
MsgBox ("[Please select data to copy into the new sheet, then press 'OK']")
newWs.Cells(1,1).PasteSpecial '### Modify to your specific location to paste the data
'Here you can add logic to validate that they have pasted enough data,
' and use control statement to prompt them to paste more data, etc.,
' if necessary, or exit sub early
'For example:
If WorksheetFunction.CountA(newWS.Cells(1, 7)) < 1 Then
MsgBox "Try again!"
Exit Sub
End If
Alternatively, you can use a DataObject:
Dim dataObj As New MSForms.DataObject
dataObj.GetFromClipboard
newWs.Cells(1,7).Value = dataObj.GetText
You could restructure the code so that it lives inside of a userform with ShowModal set to false (in the properties). Code prior to when you want the user to gather data can be put in the useform's initialize event. Then the userfrom shows (with a simple label caption and an okay button). Since it is modeless the user can copy data from an external program and paste it in. Then the rest of the code runs after the user hits okay. The form itself can be hidden during this phase. As proof of concept I created the following form:
with the following code:
Private Sub CommandButton1_Click()
Me.Hide
MsgBox Range("A1").Value
Unload Me
End Sub
Private Sub UserForm_Initialize()
'macro code can go here
'it runs before the form shows
'e.g.
MsgBox "Initializing"
End Sub
I launch the form on a blank sheet. First a message box appears before the code (confirming that code can run while the form is being initialized but before it is visible) then the form shows:
I go to an open instance of Notepad which contain a sentence and, while the form is still open -- paste it into A1:
Finally I press okay and the userform then hides itself but continues to run code (which now has access to the copied data):
Remember to unload the form at the end.

Exporting Access Query to Excel

I've got an Access 2007 database on which I have created around 15 SQL queries to process specific data, I have created a main frame navigation menu using menus in Access, I now need to extract all th queries to Excel using VBA code, I have managed to do this with the code below by creating a button and specifying this code to it.
Private Sub query1_Click()
DoCmd.TransferSpreadsheet acExport, _
acSpreadsheetTypeExcel9, "Total Users and Sessions", _
"C:\UsersandSessions.xls", , "Total Users & Sessions"
End Sub
Now my problem at the moment is that fine the query is exported to Excel, but it is done so without any formatting applied at all, I would like to add some formatting at least to the headers and maybe a title inside the spreadsheet, and one thing I dont really like is that all records are being started from the first cell. Also I would prefer that if I hit that button again in Access and the Excel spreadsheet has already exists with that query output then when clicked again it will write again to a the next available sheet.
Any suggestions or ideas a very welcome.
The short story, is you can't. You might be able to do some scripting on the Excel side to format the resulting file. If you want something pretty, you probably want to create a report.
You could, instead mount the excel sheet as a table, and then on a separated sheet in the excel file, reference the first sheet, and format the second sheet for viewing.
if you use DoCmd.TransferSpreadsheet and create an original and then edit it so that the formatting is correct, you can then run DoCmd.TransferSpreadsheet again and it will update the file with the values but keep the formatting.
However, if a human then changes the file by adding new tabs, or adding calculations, etc, then the DoCmd.TransferSpreadsheet will no longer work and will fail with an ugly error message. So what we do in our enviroment is DoCmd.TransferSpreadsheet to an original file with formatting, and follow that up in the VBA by copying the file to the users desktop, and then opening that copy so the user doesn't mess up the original source excel file.
This approach is a minimum code, clean, and easy to maintain solution. But it does require a extra "source" or original file to be hanging around. Works in Access 2007.
You also would like the results to end up on a new tab. Unfortunately, I think it will take some excel automation to do that. The VBA inside Acccess can call a function inside the VBA in Excel. That VBA could then copy the tabs as needed.
My idea would be a hybrid of Excel automation from Access and creating a template in Excel as well that would have a data table linked to your query.
To start create your data table in Excel. You can start three rows down and two columns to the right if you want or wherever. Go to your data tab and click access, find your db, choose your query you want to link to, choose table as the radio button but click properties next instead of ok, uncheck the enable background refresh, this part is critical ... under the definition tab in the connection string you will see a part that says Mode=Share Deny Write change that to Mode=Read, this will make sure that the query refreshes without errors from an MS Access VBA while the db is open and will keep your users from writing back to the db in case your query is a writeable query. Once you set that up you can adjust the table formatting however you choose from the table design tab and it will keep that formatting.
For the purposes of this we are going to assume you started the table in cell B4 ,and your named the worksheet CurrentDay, for purpose of the following VBA example be sure to replace that reference with your actual placement.
Next go back to Access and write your VBA first ensure that in your VBA window you have the reference to Microsoft Excel 12.0 Object Library is selected by going to Tools > References and selecting it from the alphabetical listing.
Create your sub as follows:
Sub query1_click()
Dim xl as Excel.Application
Dim wbk as Excel.Workbook
Dim wks as Excel.Worksheet
Dim RC as Integer
Dim CC as Integer
Set xl = New Excel.Application
Set wbk = xl.wbk.Open "X:\Filelocation\FileName.xlsx" 'name and path you saved the file you previously created
xl.Visible = True
'The above is not necessary but you may want to see your process work the first few times and it will be easier than going to task manager to end Excel if something fails.
RC = xl.Application.CountA(xl.wbk.Worksheets("CurrentDay").Range("B:B")) + 3 'This will count the rows of data in your table including your header so you can copy the data to another tab dynamically as the size of your table expands and shrinks we add 3 to it because we started at row 4 and we need the location of the last row of the record set.
CC = xl.Application.CountA(xl.wbk.Worksheets("CurrentDay").Range("4:4")) + 1 'This counts the header row and adds one space because we will use this as a location holder for our copy / paste function
Set wks = xl.wbk.Worksheets.Add
wks.Name = format(date(),"MM_dd_yy") 'this will name the tab with today's date... you can eliminate this step if you just want the sheets to be the generic Sheet1, Sheet2, etc.
With xl.wbk
.Worksheets("CurrentDay").Range(Cells(4,2),Cells(RC,CC)).Copy
.wks.PasteSpecial xlPasteValues 'This pastes the values so that the table links do not paste otherwise every tab would just refresh everyday.
.wks.PasteSpecial xlPasteFormats 'This gets your formatting.
.RefreshAll 'This will refresh your table
Wend
With xl
.Save
.Close False
.Quit
Wend
Set xl = Nothing
Set wbk = Nothing
Set wks = Nothing
End Sub
That should get you to have your data to not start on A1 of your sheets, save your old data each time, and automate the steps from access.

Resources