Is there a way to copy the selected text within a text box with VBA Excel? - excel

I have replaced the ctrl+c shortcut with a macro that performs additional instructions when copying a range.
When the selection is not a range, the program should simply copy the current selection. It seemed to work perfecly fine until I tried to copy some text from within a TextBox (and basically any text that is within an object). When pasting, it just pastes the object and not the selected text within the object.
Here's my code :
Sub ShadowCopy()
Dim Rg As Range, Source As Range
Dim Ad As String, Nm As String, flag As Integer, i As Integer, obj As Integer
Dim Hs As Integer, Ls As Integer, y As Integer
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
obj = 0
If TypeName(Selection) <> "Range" Then
Selection.Copy
obj = 1
Else
If Application.CutCopyMode = False Then
Set Source = Application.Selection
Nm = Source.Worksheet.name
Hs = Application.Min(Source.Rows.Count, 1000)
Ls = Application.Min(Source.Columns.Count, 1000)
Ad = Source.Address
flag = 0
For i = 1 To ActiveWorkbook.Worksheets.Count
If ActiveWorkbook.Worksheets(i).name = "ShadowCopy" Then
Sheets("ShadowCopy").Columns(1).Clear
Sheets("ShadowCopy").Columns(3).Clear
flag = 1
End If
Next i
If flag = 0 Then
Sheets.Add(After:=Sheets(Sheets.Count)).name = "ShadowCopy"
Source.Worksheet.Activate
End If
Worksheets("ShadowCopy").Visible = False
Sheets("ShadowCopy").Cells(1, 1) = Nm
Sheets("ShadowCopy").Cells(2, 1) = Ad
Sheets("ShadowCopy").Cells(3, 1) = Hs
Sheets("ShadowCopy").Cells(4, 1) = Ls
For y = 1 To Hs
Sheets("ShadowCopy").Cells(y, 3) = Source.Rows(y).RowHeight
Next y
End If
End If
Application.Calculation = xlCalculationSemiautomatic
Application.ScreenUpdating = True
If obj = 0 Then
Source.Copy
End If
End Sub
The part that does not work as intended is:
If TypeName(Selection) <> "Range" Then
Selection.Copy
obj = 1
It is as if the selection does not change when I select the text in the TextBox. However, when I recorded the text selection, the corresponding code implies that my selection should have changed when I selected the text in the TextBox:
ActiveSheet.Shapes.Range(Array("TextBox Source")).Select
Is there a way to copy the text highlighted by the cursor in a TextBox/Object ?
Thank you for your answers !

Related

merging sheets from left to right, not top down using range method

i just like to open several source files (all excel) and always copy the complete data rom sheet 1 into my target-sheet. First part works well.
The unusual thing is that i want the tables to be merged from the left to right (horizontical), not from top down.
Of course the range needs to adjust dynamically. The allocation part is also working. Whats not working is to copy it over my target sheet and always add from left to right.
Means
Worksheet 1 hast data from A1:C10
Worksheet 2 has data from A1:B20
should be merged like
Worksheet 1 hast data from A1:C10 -> A1:C10
Worksheet 2 has data from A1:B20 -> D1:E20
etc. I cannot do this. It either gives me a 1004, or says that the object doesnt support the method.
Here's the code:
Application.ScreenUpdating = False 'Das "Flackern" ausstellen
Set oTargetSheet = ActiveWorkbook.Sheets.Add
lErgebnisSpalte = 1
sPfad = "C:\Users\TEST\"
sDatei = Dir(CStr(sPfad & "*.xl*"))
Do While sDatei <> ""
Set oSourceBook = Workbooks.Open(sPfad & sDatei, False, True)
z1 = oSourceBook.Sheets(1).UsedRange.Rows.Count
s1 = oSourceBook.Sheets(1).UsedRange.Columns.Count
**oSourceBook.Sheets(1).Range(oSourceBook.Cells(1, 1), oSourceBook.Cells(z1, s1)).Copy oTargetSheet.Range(oTargetSheet.Cells(1, lErgebnisSpalte), oTargetSheet.Cells(z1, s1))**
lErgebnisSpalte = lErgebnisSpalte + 1
oSourceBook.Close False 'nicht speichern
'Next File
sDatei = Dir()
Loop
Application.ScreenUpdating = True 'Das Bildschirm-Aktualisieren wieder einschalten
'Variablen aufräumen
Set oTargetSheet = Nothing
Set oSourceBook = Nothing
End Sub
Debug keeps saying:
Object doesnt support the method; and marks this line:
**oSourceBook.Sheets(1).Range(oSourceBook.Cells(1, 1), oSourceBook.Cells(z1, s1)).Copy oTargetSheet.Range(oTargetSheet.Cells(1, lErgebnisSpalte), oTargetSheet.Cells(z1, s1))**
This works for me (in this case I just copy the existing range into the next free column)
Private Sub Worksheet_Activate()
Dim colNr As Integer
For i = 1 To 100
colNr = ThisWorkbook.ActiveSheet.Range("A1").End(xlToRight).Column
colNr = colNr + 1
ThisWorkbook.ActiveSheet.Range("A1:B5").Copy Destination:=ThisWorkbook.ActiveSheet.Cells(1, colNr)
Next i
End Sub
I hope this helped.

Count rows and export based on criteria

So I have an Excel file, that I want to export some of the rows to another Excel file, my problem is that I have a row that is like:
1
1
1
2
2
2
3
3
3
1
1
1
And I want to export from the first row with number one to the last row with number 3, and after exportation delete that same lines.
So far i have this.
Private Sub export2()
folha = exportform.Label14.Caption
On Error GoTo ErrHandler
Application.ScreenUpdating = False
Dim src As Workbook
' ABRIR EXCEL
Set src = Workbooks.Open("U:\Mecânica\Produção\OEE\OEE ( FULL LOG )\FRS\FRS_DADOS.xlsx", True, False)
WS_Count = src.Worksheets.Count
For o = 1 To WS_Count
src.Worksheets(o).Unprotect password:="registoOEE"
Next o
lastsrc = src.Worksheets("DADOS").Range("A65536").End(xlUp).Row
last = Application.ThisWorkbook.Worksheets(folha).Range("A65536").End(xlUp).Row
Dim last, I As Integer
Dim turno As String
Sheets(folha).Select
For I = 2 To last
'If application.ThisWorkbook.Worksheets(folha).Cells(last, 61)
Next I
ErrHandler:
Application.EnableEvents = True
Application.ScreenUpdating = True
For o = 1 To WS_Count
src.Worksheets(o).Protect password:="registoOEE"
Next o
Application.DisplayAlerts = False 'IT WORKS TO DISABLE ALERT PROMPT
'SAVES FILE USING THE VARIABLE BOOKNAME AS FILENAME
src.Save
Application.DisplayAlerts = True 'RESETS DISPLAY ALERTS
' CLOSE THE SOURCE FILE.
src.Close True ' FALSE - DON'T SAVE THE SOURCE FILE.
Set src = Nothing
fim:
End Sub
I've edited so you can see what code i have already, hope it helps.
Answering this 10 months old question as it might help someone who is still searching for similar kind of results.
I have put a count if formula in AI column to count the number of occurrences of value in AH and if the the AI value is greater than 1 the same will be pasted in different sheet.
Here is the code:
Sub CopyDups()
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
Dim cnt As Range
Dim nu As Integer
Dim Source As Worksheet
Dim Target As Worksheet
Set Source = ActiveWorkbook.Worksheets("SourceData")
Set Target = ActiveWorkbook.Worksheets("Criteria 1")
nu = 1
For Each cnt In Source.Range("AI1:AI1000")
If cnt > 1 Then
Source.Rows(cnt.Row).Copy Target.Rows(nu)
nu = nu + 1
End If
Next cnt
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub

Run Time Error '380' on ListBox [Could not set the Selected property. Invalid property value.]

I’ve reviewed 10s of reported problems with similar error code but none match my scenario..
I have a ListBox that I populate using the .List property... The ListBox behaves as expected except when (in sequence):
1. I filter out non-selected items and reset the .List property with the filtered items (no issues there)
2. I attempt to “mark” all items as selected (I get the error as soon as I set the .Selected property for the first item).
Here is the code (I’ve tried many different variations, but this is the “cleanest”):
Set rngTarget = rngTarget.Range(rngTarget.Cells(2, 1), rngTarget.Cells(rngTarget.Rows.Count, lbSelection.ColumnCount))
lbSelection.Clear
lbSelection.List = rngTarget.Cells.Value
lItemCnt = lbSelection.ListCount - 1
For lItemNdx = 0 To lItemCnt
lbSelection.Selected(lItemNdx) = True
Next lItemNdx
The error occurred on the first encounter of lbSelection.Selected(lItemNdx) = True. All the indices are valid, the dataset/range is valid with all rows/columns having valid data, and there are only 5 columns in the list (i.e., less than the max of 10). I’ve also tried to first assign the dataset (range) to a variant and then the variant to the .List property, but that didn’t make a difference. I’ve also tried “unmarking” all items before clearing the list.. What is interesting is that, in the debugger when the error is encountered, the .ListCount property shows the correct number of rows. HOWEVER, the GUI shows a blank list.
Any help would be greatly appreciated.
P.S. Populating the ListBox “manually” using .AddItem method is not a practical option for my purposes (nor using .RowSource property).
Environment: Excel 2010, standard. Windows 7 Pro.
Enclosing fuller code for review (data not enclosed but consists of 457 rows [first row is header and not part of the listbox] and 5 columns --all text). To replicate the issues, simply deselect the first item in the list.
Button to call userform:
`Sub LoadSampleForm()
frmTestLB.InitControls
End Sub`
Userform code:
` Option Explicit
Private bIgnorEvents As Boolean
Public Sub InitControls()
Dim lItemNdx As Long
Dim lItemCnt As Long
bIgnorEvents = True
lbSelection.Clear
lbSelection.ColumnCount = 5
lbSelection.ColumnWidths = "45 pt;155 pt;70 pt;70 pt;70 pt"
lbSelection.List = Worksheets("Sample").Range(Worksheets("Sample").Cells(2, 1), Worksheets("Sample").Cells(457, 5)).Value
lItemCnt = lbSelection.ListCount - 1
For lItemNdx = 0 To lItemCnt
lbSelection.Selected(lItemNdx) = True
Next lItemNdx
bIgnorEvents = False
Me.Show
End Sub
Private Sub lbSelection_Change()
Dim bAppAlert As Boolean
Dim lItemCnt As Long
Dim lItemNdx As Long
Dim lKeyColNdx As Long
Dim rngTarget As Range 'Temporary range for items to be searched
Dim wsTemp As Worksheet 'Temporary worksheet used for target range and applying Lookup function
If (Not bIgnorEvents) Then
bIgnorEvents = True
Set wsTemp = ThisWorkbook.Worksheets.Add
lKeyColNdx = 1
lItemCnt = lbSelection.ListCount + 1
wsTemp.Range(Cells(2, 1), Cells(lItemCnt, lbSelection.ColumnCount)).Value = lbSelection.List
Set rngTarget = wsTemp.Range(Cells(1, 1), Cells(lItemCnt, lbSelection.ColumnCount + 1))
rngTarget.Cells(1, lbSelection.ColumnCount + 1).Value = "Selected"
For lItemNdx = 2 To lItemCnt
If (lbSelection.Selected(lItemNdx - 2)) Then
rngTarget.Cells(lItemNdx, lbSelection.ColumnCount + 1).Value = 1
Else
rngTarget.Cells(lItemNdx, lbSelection.ColumnCount + 1).Value = 0
End If
Next lItemNdx
rngTarget.AutoFilter Field:=lbSelection.ColumnCount + 1, Criteria1:="=0"
rngTarget.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
wsTemp.AutoFilterMode = False
Set rngTarget = rngTarget.Range(rngTarget.Cells(2, 1), rngTarget.Cells(rngTarget.Rows.Count, lbSelection.ColumnCount))
lbSelection.Clear
lbSelection.List = rngTarget.Cells.Value
lItemCnt = lbSelection.ListCount - 1
For lItemNdx = 0 To lItemCnt
lbSelection.Selected(lItemNdx) = True
Next lItemNdx
'Clean-up: Remove temp sheet without prompts
bAppAlert = Application.DisplayAlerts 'Current setting
Application.DisplayAlerts = False 'Supress DisplayAlerts
wsTemp.Delete 'Delete temp sheet
Application.DisplayAlerts = bAppAlert 'Restore original DisplayAlerts setting
Set rngTarget = Nothing
Set wsTemp = Nothing
bIgnorEvents = False
End If
End Sub`
Try changing the line:
lbSelection.List = rngTarget.Cells.Value
To:
lbSelection.List = rngTarget

Loop Through CheckBox Controls in VBA UserForm

I have a user form in Excel VBA with a check box for each month.
Selecting one or more cause the required month to be shown on the sheet, I copy-pasted the code 12 times and it works but I'm sure there is a better way doing it with a For loop.
This is a part of my code (it goes on 12 times):
If CheckBox1.Value = True Then
ActiveSheet.PivotTables("PivotTable1").PivotFields("month").PivotItems("1").Visible = True
Else
ActiveSheet.PivotTables("PivotTable1").PivotFields("month").PivotItems("1").Visible = False
End If
If CheckBox2.Value = True Then
ActiveSheet.PivotTables("PivotTable1").PivotFields("month").PivotItems("2").Visible = True
Else
ActiveSheet.PivotTables("PivotTable1").PivotFields("month").PivotItems("2").Visible = False
End If
I tried writing:
for i in range 1 to 12
and then writing my code but there seem to be a problem when I put "i" instead of the numbers.
Assuming you aren't using Tristate checkboxes, then the .Value can only be True or False, so we should be able to get away with something like this:
(Assumes your code runs inside the UserForm, so that Controls is directly accessible)
Dim mthIdx as Long
Dim nm as String
Dim c As Control
With ActiveSheet.PivotTables("PivotTable1").PivotFields("month")
For mthIdx = 1 To 12
nm = "CheckBox" & mthIdx
Set c = Controls(nm)
.PivotItems(mthIdx).Visible = c.Value
Next
End With
(The With clause isn't strictly necessary, but it's usually a good idea to resolve nested COM references as infrequently as possible)
Try this ..
Dim i As Integer
Dim sN As String
Dim chx As MSForms.CheckBox
Dim obj As OLEObject
For i = 1 to 12
sN = format(i)
Set obj = OLEObjects("CheckBox" & sN)
Set chx = obj.Object
If chx.Value = True Then
ActiveSheet.PivotTables("PivotTable" & sN).PivotFields("month").PivotItems(sN).Visible = True
Else
ActiveSheet.PivotTables("PivotTable" & sN).PivotFields("month").PivotItems(sN).Visible = False
End If
Next
I've not checked the code but this should put you along thr right path if it's not spot on though...
For i = 1 to 12
If CheckBox(i).Value = True Then
ActiveSheet.PivotTables("PivotTable1").PivotFields("month").PivotItems(i).Visible = True
Else
ActiveSheet.PivotTables("PivotTable1").PivotFields("month").PivotItems(i).Visible = False
End If
Next i

When reading down a column of Excel file, how to define cell coordinates without selecting a cell?

Can anyone tell me how to improve this macro?
All the macro does is it just reads an Excel file for a list a accounts to update in an application (SmarTerm Beta). It technically already accomplishes the goal, but is there a way to code it so that while it’s reading the Excel file, the coordinates of the cells from which to read the account numbers and also the coordinates of the cells in which to write an output don’t depend on a "pre-selected" a cell? The risk with selecting a cell is that if someone were to accidentally select a different cell while the macro is running, everything will get screwed up.
Here's my current code:
Public oExcelObj As Object
Function WaitSystem(Optional NoDialog as Variant) As Boolean
Dim nContinue as Integer
Dim nTimeOut as Integer 'In seconds.
'The default timeout for each command is 3 minutes.
'Increase this value if your host requires more time
'for each command.
nTimeOut = 10
If IsMissing(NoDialog) then NoDialog = False
'Wait for response from host.
Session.EventWait.Timeout = nTimeOut
Session.EventWait.EventType = smlPAGERECEIVED
Session.EventWait.MaxEventCount = 1
WaitSystem = True
If Session.EventWait.Start = smlWAITTIMEOUT Then
If NoDialog Then
WaitSystem = False
Else
nContinue = QuerySyncError()
If nContinue <> ebYes then WaitSystem = False
End If
End If
Set LockStep = Nothing
End Function
'Establish link. Search for Excel.
Function OleLinkConnection
Const XlMaximized = &HFFFFEFD7
Titlebar$ = AppFind$("Microsoft Excel")
If Titlebar$ <> "" Then
bIsExcelActive = True
If AppGetState(Titlebar$) = ebMinimized Then
AppSetState 2, Titlebar$
End If
Else
bIsExcelActive = False
End If
If bIsExcelActive Then
'Create Excel Object using current instance of Excel.
Set oExcelObj = GetObject(, "Excel.Application")
Else
'Create Excel Object using a new instance of Excel.
Set oExcelObj = CreateObject("Excel.Application")
End If
Version = oExcelObj.Application.Version
oExcelObj.ScreenUpdating = True
oExcelObj.Displayalerts = True
oExcelObj.Visible = true
End Function
Sub JPBmacro
Dim AccountNumber As String
Dim Temp As Integer
Begin Dialog StartDialogTemplate ,,211,74,"Run JPBmacro?"
OKButton 60,12,92,20,.Proceed
CancelButton 60,40,92,20,.Exit
End Dialog
Dim StartDialog As StartDialogTemplate
r% = Dialog(StartDialog)
If r% = 0 Then End
g$ = "G:\DATA\outputfile.xlsx"
oleCode = OleLinkConnection
oExcelObj.Workbooks.Open g$
oExcelObj.Range("A1").Select ‘<----This selects the cell from which all coordinates are based off of. The coordinates of oExcelObj.ActiveCell.Offset(Y,X).Value VBA depend on selecting a cell.
NEXTACCOUNT:
Temp = 0
AccountNumber = oExcelObj.ActiveCell.Offset(Temp,0).Value
While AccountNumber <> ""
Session.SendKey "CLEAR"
If WaitSystem = False Then End
Session.Send "ACTU " & AccountNumber
Session.SendKey "ENTER"
If WaitSystem = False Then End
If Trim(Session.ScreenText(4,6,1,22)) = "INVALID ACCOUNT NUMBER" Or Trim(Session.ScreenText(4,6,1,19)) = "ACCOUNT NOT ON FILE" Then
oExcelObj.ActiveCell.Offset(Temp,1).Value = Trim(Session.ScreenText(4,6,1,22))
GoTo RESTARTLOOP
End If
UPDATEIOV:
If Trim(Session.ScreenText(13,76,1,1)) = "Y" Then
oExcelObj.ActiveCell.Offset(Temp,1).Value = "Account already flagged as institutional."
Else
Session.Row = 13
Session.Column = 76
Session.send "Y"
Session.SendKey "ENTER"
If WaitSystem = False Then End
oExcelObj.ActiveCell.Offset(Temp,1).Value = Trim(Session.ScreenText(24,2,1,50))
End If
RESTARTLOOP:
Temp = Temp + 1
AccountNumber = oExcelObj.ActiveCell.Offset(Temp,0).Value
Wend
ENDNOW:
oExcelObj.Workbooks.Close
MsgBox "All Done!"
End Sub
Why not keep the reference to the first cell?
Dim rng as Range
Set rng = oExcelObj.Range("A1")
i=1
...
x = rng.Cell(i,1).Value
'Or faster yet is reading all the values into an variant array.
Dim array() as Variant
array = rng.Resize(N,M).Value
' Work with array as
x = array(i,1)
Given the comment from assylias and that another poster has since "answered" with this approach:
I can't see where oExcelObj is instantiated? Or how you are referring to a specific sheet.
Regardless of which,
you can avoid select by setting a range, ie Set rng1 = oExcelObj.Sheets(1).Range("A1")
and then use offsets from rng1.
The user won't be able to interfere while the code is running

Resources