.PasteSpecial doesnt work for Range object - vba

Y helo thar,
actually my vba-knowledge is quite good and normally I don't have many difficulties coding , but this is driving me nuts.
Code is pretty easy. I have a worksheet PR_DB where all my projects are stored. For every project there are a number of employees, saved in cells (sel_pr, >10+) (employee name and ID).
I want to delete an employee from the project and tidy up the project database entry. All employees are listed in two listboxes. The ones that are working in the project, and the ones that don't. Via the buttons I can add and remove employees from either listbox.
When I add an employee to a project (top button), my Sub just puts the ID&Name at the end of the row of said project.
When I remove them from a project and therefore from the database, I look for the cell with the employee data. Afterwards I just want to cut all the cells to the right and paste them one cell to the left (via offset) so the deleted name is overwritten.
This is my code:
Sub delMA_from_prBetList()
Dim i, j, k, listRow, lastRowMA_DB, lastRowPR_DB, sel_pr As Integer
Dim wsPR, wsMA_DB, wsPR_DB As Worksheet
Dim foundMA As Boolean
Dim cutRng, pasteRng As Range
Set wsPR = Worksheets("Projekte")
Set wsMA_DB = Worksheets("MA_DB")
Set wsPR_DB = Worksheets("PR_DB")
lastRowPR_DB = wsPR_DB.UsedRange.Rows.Count
'check if any employee was selected
If IsNull(wsPR.prBetListe.Value) = True Then
MsgBox "Please select an employee."
Exit Sub
End If
j = 10
'look for selected project in DB
For i = 2 To lastRowPR_DB
If wsPR_DB.Cells(i, 1) = CInt(wsPR.prListe.Value) Then
'row ID of said project
sel_pr = i
End If
Next
'find employee
Do Until wsPR_DB.Cells(sel_pr, j) = ""
'employees are saved as "ID;NAME"
If wsPR_DB.Cells(sel_pr, j) = wsPR.prBetListe.Value & ";" & wsPR.prBetListe.Column(1, wsPR.prBetListe.ListIndex) Then
'when found, look for last cell with an entry
k = j
Do Until wsPR_DB.Cells(sel_pr, k) = ""
k = k + 1
Loop
'set cutRng so it spans from cell right to the found employee
'to last cell with an employee in that project
Set cutRng = wsPR_DB.Range(wsPR_DB.Cells(sel_pr, j + 1), wsPR_DB.Cells(sel_pr, k))
'set pasteRng like cutRng, just one cell further to the left
'so the deleted employee will be overwritten
Set pasteRng = cutRng.Offset(rowOffset:=0, columnOffset:=-1)
cutRng.Cut
pasteRng.PasteSpecial
Exit Do
End If
j = j + 1
Loop
're-initialize listboxes
Call init_maListe_dyn
Call init_prBetListe_dyn
End Sub
So whats the problem? Everything works just fine, all the cells I want to cut go into clipboard, but they arent pasted into the pasteRng. Error is
Error 1004 "Application-defined or Object-defined error". I tried a thousand things but the solution is probably too easy to find.
Hope you can help me, thanks in advance.
PS: I'm kind of in a hurry, so that text might not be as well formatted as it could be. Please bear with me.

just use directly:
cutRng.Cut pasteRng
this should solve your problem ;)

If you want to offset one column to the left it should be
Set pasteRng = cutRng.Offset(,-1)
Also, you're not defining how you want to paste. The paste settings may not be set to paste values if they were set differently prior to this instance (via code or otherwise). If you want to just cut-paste the values it would be
cutRng.Cut
pasteRng.PasteSpecial xlPasteValues
Let me know if that helps at all and if not I'll look further into it.

Related

Extracting hyperlink from a range and writing them on another range

I'm new to this site, but I have already found some nice advice on how to solve problems in VBA. Now I'm here to ask help on a sub that gives me problems with Hyperlinks.
In particular, my problem is similar to the one described in this topic:
Excel VBA Get hyperlink address of specific cell
I have a worksheet full of hyperlink, but I need to extract only the addresses present in the "H" column, starting from "H6" and writing them into the "N" column, starting from "N6".
I put down this code:
Sub EstraiIndirizzoPut()
Dim IndirizzoInternet As Hyperlink
Dim ISINs As String
i = 6
For Each IndirizzoInternet In Sheets("XXX").Range("H" & i).Hyperlinks
IndirizzoInternet.Range.Offset(0, 6).Value = IndirizzoInternet.Address
ISINs = Mid(IndirizzoInternet.Address, 78, 12)
Range("N" & i).Value = ISINs
i = i + 1
Next
End Sub
It works fine only for the first "H6" cell, but at the "Next" point, when it should read the "H7" cell, it goes instead to "End Sub", terminating the routine, altough the "H7" cell, as well many others down the column, are filled with hyperlinks (it gives me "Nothing" value).
Could you please suggest me where I get this wrong? Many thanks.
Your loop isnt set up correctly. Try it like this instead:
For i = 6 to 100
Set IndirizzoInternet = Sheets("XXX").Range("H" & i).Hyperlinks
IndirizzoInternet.Range.Offset(0, 6).Value = IndirizzoInternet.Address
ISINs = Mid(IndirizzoInternet.Address, 78, 12)
Range("N" & i).Value = ISINs
Next
How do you know when to stop the loop? Is it a preset number of rows? If it not, you will want to have something determine the last row to process and replace the 100 with that variable.

find out cell address having = sheet name

I'm just a beginner for VBA but advance in MS excel. that's why I am very much interested to learn VBA.
ok this is my first question here
Actully i need to format excel sheet where file name is = sheet1 name and it is somewhere in column "A" so I want to select & delete all the rows above this cell & below untill there is a blank cell/row.
I have tried much with InStr & find function but no succeed. Also try to find cell address like B5 but could no do that.
Welcome to StackOverflow. As you have already been informed by newguy, when posting a question you should also show what you have tried so far... some piece of code, printscreens, etc.
Your explanation was not that clear (at least to me), but based on what I have understood, I have made a small code sample for you to get you started. I have broken down the code into the function blocks, so that you can better understand what they are trying to achieve.
Here is the code:
'the following function will find cell with the specific text
Private Function FindCell(ws As Worksheet, strToSearch As String, Optional sColumn As String = "A") As Integer
Dim iCounter As Integer
'as you do not know where exactly it exists, we loop from first cell in the particular row
'to the very last celll
With ws
For iCounter = 1 To .Range("A65000").End(xlUp).Row ' or .UsedRange.Rows.Count, or any other method
If .Range(sColumn & iCounter).Value = strToSearch Then
'yay, we have found the cell!
'pass out the reference
FindCell = iCounter
'now call exit function as we no longer need to continue searching for the cell (we have already found it!)
Exit Function
End If
Next iCounter
End With
'in case the cell does not exist, we can return -1
FindCell = -1
End Function
'the following cell will search the very first cell to the top (starting from specific row), which is blank / empty
Private Function FindEmptyCell(ws As Worksheet, iStartRow As Integer, Optional sColumn As String = "A") As Integer
'This function does the same, as if you have selected specific cell
'and then pressed left Ctrl + Up arrow at the same time
'Try it!
'You can do the same with Right + Left + Bottom arrow as well
FindEmptyCell = ws.Range(sColumn & iStartRow).End(xlUp).Row + 1
End Function
Private Sub EraseRows()
Dim iStartCell As Integer
Dim iEndCell As Integer
On Error GoTo 0
'First let's find the "bottom" cell which is the cell with the specific text you are looking for
iEndCell = FindCell(ActiveSheet, "TextIAmLookingFor")
'now let's see find the top blank cell (so that we get the range of from - to that you want to erase)
iStartCell = FindEmptyCell(ActiveSheet, iEndCell)
'now we can delete the rows!
'iEndCell-1 because you don't want to erase the cell with your search string, right?
ActiveSheet.Rows(CStr(iStartCell) & ":" & CStr(iEndCell - 1)).EntireRow.Delete (xlUp)
End Sub

Copy and Paste Error : '1004'

I am using VBA to help manage a set of data. I will have Monthly Data for 50 months and I wish to categorize it into different sheets based on the FIRST word within a cell. Here is what I done so far;
I created a workbook with 2 sheets,
Sheet1(Employee Inventory)
Sheet2(PB)
and my code is written and saved in this Workbook.
Sub myCode()
Dim OldString As String
Dim NewString As String
Set i = Sheets("Employee Inventory")
Set PB = Sheets("PB")
Dim counterPB
counterPB = 2
Dim d
Dim j
d = 1
j = 2
Do Until IsEmpty(i.Range("D" & j))
OldString = i.Range("D" & j)
NewString = Left(OldString, 2)
If NewString = "PB" Then
i.Rows(j).EntireRow.Copy
PB.Range("A" & counterPB).Select
PB.Paste
counterPB = counterPB + 1
End If
j = j + 1
Loop
End Sub
Apologies for the code as it looks weird. This code looks at Sheet1 and scans column "D" and looks for the first word starting with "PB". Once it does find it, it will copy and paste the whole row into another sheet called Sheet2(PB).
When I am in Microsoft Visual Basic window AND I have the Excel Spreadsheet with Sheet1(Employee Inventory) tab opened and when I click Run Sub I get the following error: Run-time error '1004': Application-defined or object-defined error. When I click on "PB" tab, nothing is being copy and pasted in there.
HOWEVER, when I click on the PB tab and then I click Run Sub, the codes executes and any rows containing the first word "PB" will be copied and pasted in the "PB" tab.
My question is, why does it only work when I have the Sheet2 opened and not when I have Sheet1 Opened?
when use range.select its parent worksheet must be selected, so we can use PB.Activate or not use .select at all.
Try to replace this:
i.Rows(j).EntireRow.Copy
PB.Range("A" & counterPB).Select
PB.Paste
with this line:
i.Rows(j).Copy PB.Rows(counterPB)
Why don't you just select the second sheet at the beginning of the code?
Try the following
ActiveWorkbook.Sheets("Sheet2").Activate
If it really works when this sheet is selected, then it should work with this.

excel - find and highlight text from one sheet on second sheet

I am getting killed by excel, I'm not 100% sure it can do exactly what I'm needing. I've tried various functions and can come close, but none are perfect. I've uploaded a spreadsheet as an example. I have a sheet of mailboxes, followed by a cell with the users who have access to the mailbox. The cell has anywhere from 0 to 5 users separated by commas. The second sheet has a list of users. What I need is a way to parse out the first sheet, either highlight on the first sheet, or copy to another sheet; all the mailboxes that all the associated users match in the second cell appear on the second sheet.
The real world sheet I have has over 2500 mailboxes with as many as 205 (as few as 0) associated users, so I desperately need a way to mechanically filter the sheet. I'm trying to filter the mailboxes that all the associated users are present on a second sheet.
I've tried using vlookup, index/match and a few others, and what seems to trip it up is having the comma separation. Using ""& cell_i'm_looking_for &"" returns nothing so I'm guessing I need to try something else. I also have the sheet with all the users in separate cells.
I downloaded your sheet and created a module with the following function inside of it:
Function mymailboxes(who As Range, lookup As Range)
Dim myRow As Range
For Each myRow In lookup
If InStr(myRow.Cells(1, 2).Value, who.Value) > 0 Then
myReturn = myReturn & "," & myRow.Cells(1, 1).Value
End If
Next
'cut off the first ,
myReturn = Right(myReturn, Len(myReturn) - 1)
mymailboxes = myReturn
End Function
Then on Sheet 2, Cell E2 I gave the following formula: =mymailboxes(A2, Sheet1!A1:B50) which gave me the following results: mailbox1,mailbox2,mailbox4,mailbox8,mailbox12,mailbox17,mailbox21,mailbox25,mailbox28,mailbox34,mailbox39,mailbox41,mailbox42,mailbox44,mailbox49,mailbox50
I hope this helps.
To get a list of invalid users the following function will help.
Function get_invalid_users(users As Range, validusers As Range)
Dim myRow As Range
myusers = Split(users, ",")
myReturn = ""
For Each user In myusers
is_valid_user = False
'Guilty until proven innocent
For Each myRow In validusers
If myRow.Cells(1, 1).Value = user Then
is_valid_user = True
'Proven innocent, break out of the loop, no double jeopardy.
Exit For
End If
Next
If is_valid_user = False Then
myReturn = myReturn & "," & user
End If
Next
If Len(myReturn) > 0 Then
myReturn = Right(myReturn, Len(myReturn) - 1)
Else
myReturn = ""
End If
get_invalid_users = myReturn
End Function
Sheet 1, Cell C2 with formula: =get_invalid_users(B2, Sheet2!$A$1:$A$3) returned zx1234

Subscript Out of Range, even though value is defined

I am writing a piece of code that transfers selected data on an Excel sheet into an array, which is then used to print the data on a new spreadsheet. However, I am getting a "Subscript Out of Range" error, even though a value appears when I scroll over selectArr(i - 1). Here is my code:
Sub Marascuilo()
Dim numRows As Integer 'Number of rows selected
numRows = Selection.Rows.Count
Dim selectArr() As Double 'Array containing numbers from selected cells
selectArr = loadArr(numRows) 'Load values into array
For i = 2 To UBound(selectArr) - LBound(selectArr) + 2
Sheets("Sheet 4").Cells(i, 2).Value = selectArr(i - 1)
Next
End Sub
'This function loads the values from the selected cells into selectArr.
Function loadArr(numRows) As Double()
Dim ResultArray() As Double
r = 1
For Each v In Selection
ReDim Preserve ResultArray(1 To r)
If v <> "" Then
ResultArray(r) = v.Value
r = r + 1
End If
Next
loadArr = ResultArray
End Function
Any ideas as to how I fix this issue?
Thanks!
Jay
Instead of using Sheets("Sheet 4"), you might consider using the sheet's CodeName. If you look in the Project Explorer window, every sheet has a Name and a CodeName. It might look like this
Sheet1 (Sheet1)
Sheet2 (Sheet2)
The first one is the CodeName (can't be changed from the UI). The one in parens is the tab name. Select the sheet in the Project Explorer and press F4 to open the Properties dialog. Go to the (Name) property (a poorly named property) and change it to something meaningful. I change all my sheets' CodeNames and use a wsh prefix. My sheet that's a log has a CodeName of
wshLog
Now I can use wshLog in my code and I get some benefits. The first is that if someone renames the sheet in the UI, the code still works. The second is I can type wshlog (all lower case) and the VBE will change it to wshLog and I get that visual cue that I spelled it right. Finally, my code is more readable, ex wshFinalReport vs. Sheets("Sheet1").