This is probably super simple but If I already have a selection how can I add the next row without know necessarily what the next one is?
EDIT
For example if I have the input range "D1:D8" how can I add in the next row, ie "D1:D9" without putting in "D1:D9".
Try
Sub inc_row()
Selection.Resize(Selection.Rows.Count + 1, Selection.Columns.Count).Select
End Sub
This will increase your selection by 1 row, it will also select the new range
Sub test()
Dim rng As Range
Set rng = Range("b2:f5")
Debug.Print rng.Address 'returns $B$2:$F$5
Set rng = rng.Resize(rng.Rows.Count + 1)
Debug.Print rng.Address 'returns $B$2:$F$6
End Sub
Related
I want to use VBA to 1) Find the word “Report:” in my excel sheet (I know the word “Report:” will only appear once in the sheet); 2) Erase all the content (including the word “Report”) below this cell
So, ideally, the result should look like this:
The amount of data will change, so the word “Report:” is not going to be in the row 109 every time.
This is the code I am using now,
Sub Trial()
Set myRange = ActiveDocument.Content
myRange.Find.Execute FindText:="Report:", _
Forward:=True
If myRange.Find.Found = True Then
myRange.SetRange (myRange.End + 1), ActiveDocument.Content.End
myRange.Delete
End If
End Sub
But, it gives me a
run-time error ‘424’
Give this a try:
Option Explicit
Sub ReportKiller()
Dim Report As String, r As Range, rKill As Range
Report = "Report"
Set r = Cells.Find(Report, after:=Cells(1, 1))
If Not r Is Nothing Then
Set rKill = Range(r, r.End(xlDown))
rKill.EntireRow.Delete
End If
End Sub
It will delete all sheet content from the Report cell downward.
I've created an Excel document with a sheet, named "Plakken". This sheet contains a button which paste a table, that the user copied from an intranet page, on to the sheet "Template (2)".
In the example below, you can see the table on "template (2)"
What i like to do now, is copy some data from the pasted table to sheet "opslaan", the data i want to copy is:
Artikelnummer (article number)
Artikelnaam (article name)
datum (date)
These are the 3 left columns, for example:
But the data in the table is seperated with rows containing the word "vulgebied".
Example:
I'm searching for a way to only copy all the data listed above, and paste them on the sheet "opslaan".
The table is different every time, sometimes there are more or few lines between the "vulgebied" row, but the style of the table is always the same.
Edit:
I think something that might work is:
Option Explicit
Sub DeleteRow()
Dim i As Long
Dim rng As Range
With ActiveWorkbook.Sheets(1)
For i = 100000 To 1 Step -1
With .Cells(i, "C")
If .Value = "Vulgebied" Then
If rng Is Nothing Then
Set rng = .Cells
Else
Set rng = Application.Union(rng, .Cells)
End If
End If
End With
Next i
If Not rng Is Nothing Then rng.EntireRow.Delete
End With
End Sub
But because the word "vulgebied" contains a different number after the word, i don't know how to solve that..
Example: https://files.fm/u/n4k4z6yz
In order to find cells that might contain the word "Vulgebied", use the function Instr.
Modified Code
Option Explicit
Sub DeleteRow()
Dim i As Long
Dim DelRng As Range
Application.ScreenUpdating = False
With ThisWorkbook.Sheets("Template (2)")
For i = 100000 To 1 Step -1
If InStr(.Range("C" & i).Value, "Vulgebied") > 0 Then
If DelRng Is Nothing Then
Set DelRng = .Range("C" & i)
Else
Set DelRng = Application.Union(DelRng, .Range("C" & i))
End If
End If
Next i
If Not DelRng Is Nothing Then DelRng.EntireRow.Delete
End With
Application.ScreenUpdating = False
End Sub
Note: a safer way to make sure "Vulgebied" is found within a cell is by using the LCase function (converts the all characters of the word to lower case), see below:
If InStr(LCase(.Range("C" & i).Value), "vulgebied") > 0 Then
I'm trying to get my code to search column D for cells that are not blank. When it finds one that isn't blank it copies that cell and fills the series beneath. Then I want it to repeat this code until "D3020".
However each time I run my code it takes the copied cell and continuously pastes it all the way down to "D3020". There are different values that also need to be copied so I need to fix this. I have tried using the .offset property. I have tried using .range.copy property.
Sub Fill()
Dim SRng As Range
Dim SCell As Range
Set SRng = Range("D1101:D3020")
For Each SCell In SRng
If SCell <> "" Then
SCell.Copy
Range(SCell, SCell.Offset(10, 0)).PasteSpecial(xlPasteAll)
End If
Next SCell
End Sub
I'd like this code to search Range("D1101:D3020") for cells that <> "". When one is found, fill the series beneath it, stopping at the next cell with a number in it.
For example
D1101 = 1601166 (see picture) I want to copy this and fill the series beneath it. All are exactly ten rows apart. Then D1121 = 1601168 (see picture) I want to copy/fill series for this as well.
No need for a loop; just fill the blanks with the value above.
sub fillBlanks()
dim brng as range
on error resume next
set brng = Range("D1101:D3020").specialcells(xlcelltypeblanks)
on error goto 0
if not brng is nothing then
brng.formular1c1 = "=r[-1]c"
Range("D1101:D3020") = Range("D1101:D3020").value
end if
end sub
Option Explicit
Sub Test()
FillEmptyFromTop [D1101:D3020]
End Sub
Sub FillEmptyFromTop(oRng As Range)
Dim v, a, i
With oRng.Columns(1)
a = .Value
For i = LBound(a, 1) To UBound(a, 1)
If IsEmpty(a(i, 1)) Then a(i, 1) = v Else v = a(i, 1)
Next
.Value = a
End With
End Sub
I have a list of links in more than 100000 cells.
I have to give hyperlinks to all of them but in Excel there is a limit of 65530 hyperlinks per worksheet.
How can I overcome the limit or how can I merge cells with equal values using VBA?
Sub AddHyperlinks()
Dim myRange As Range
Set myRange = Range("A1")
Dim hText As Variant
Do Until IsEmpty(myRange)
hText = Application.VLookup(myRange.Value, Worksheets("Sheet2").Range("A:B"), 2, False)
If IsError(hText) Then
hText = ""
Else
ActiveSheet.Hyperlinks.Add Anchor:=myRange, Address:="http://" + hText, TextToDisplay:=myRange.Text
hText = ""
End If
Set myRange = myRange.Offset(1, 0)
Loop
End Sub
The solution is as mentioned by #Rory:
Use the HYPERLINK function in your cell to emulate a hyperlink via a formula.
=HYPERLINK(url, displaytext)
This effectively bypasses the built-in Excel limit on "hard-coded" hyperlinks. Just tested this out after I hit the infamous error 1004:
Application-defined or object-defined error
when trying to create 100k+ hyperlinks in a sheet.
Just regular copy paste should work, but I can update the example (not tested) if it doesn't
Sub AddHyperlinks()
Dim rng As Range, rngFrom As Range, values, r
Set rng = ThisWorkbook.Worksheets("Sheet1").Range("A1")
Set rngFrom = ThisWorkbook.Worksheets("Sheet2").Range("A:A")
rng.Worksheet.Hyperlinks.Delete ' remove all previous Hyperlinks
While rng(1) > ""
' resize the range to the same values
While rng(rng.Rows.Count + 1) = rng(1)
Set rng = rng.Resize(rng.Rows.Count + 1)
Wend
r = Application.Match(rng(1), rngFrom, 0)
If Not IsError(r) Then
values = rng.Value2 ' save the values
rngFrom(r, 2).Copy rng ' copy from the cell next to the match
rng.Value2 = values ' restore the values (not sure if it removes the links)
End If
Set rng = rng(rng.Rows.Count + 1) ' move to the next cell below
Wend
End Sub
If you store the URL in (eg) colA then something like this should work:
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
Dim URL
If Target.Column <> 1 Then Exit Sub '<< only reacting if cell in URL column is right-clicked
URL = Target.Value
ThisWorkbook.FollowHyperlink URL
End Sub
Alternatively use the Before_DoubleClick event
It does mean you can't use a "friendly" link text such as "click here", but you could likely manage that if you store the URL text at a fixed offset and then read that instead of Target.Value
I suffered from the same problem and I know that I shouldn't have more than around 120000 rows that need hyperlinking so modified some code I found in another thread to this
Sub hyperlink2()
Dim Cell As Range
Dim Cell2 As Range
Dim rng As Range
Dim Rng2 As Range
Set rng = Range("X2:X60000")
For Each Cell In rng
If Cell <> "" Then ActiveSheet.Hyperlinks.Add Cell, Cell.Value
Next
Set Rng2 = Range("X60001:X120000")
For Each Cell2 In Rng2
If Cell2 <> "" Then ActiveSheet.Hyperlinks.Add Cell2, Cell2.Value
Next
End Sub
Hope that helps someone else who stumbles upon this via google (like I did) looking for a workable solution...
The 255 character limit applies to the limit of character that can be put in one cell's formula. A common approach to this is by splitting the link into multiple cells and using a formula to combine them.
=HYPERLINK(A1&A2,"Click Here")
I have a quandary, and I don't know if it will work better using excel VBA or not. Thinking about it I believe VBA will work best, but I don't know how to make it work.
I have two pages in a workbook, one is the form, the other is the database, I want the pulldown menu from the form to populate the rest of the form. It does... what I want then is to be able to change the value of the form press submit, and the new data will overwrite the old data.
Is this possible?
Here is the link to the sheet I'm talking about.
http://dl.dropbox.com/u/3327208/Excel/Change.xlsx
Here is the script I am working with now...it takes the sheet, copies everything to a row takes that row, moves it to the NCMR Data tab and then clears the data on the new row from the original sheet.
This code technically could work, but what I need to do is make it use the same concept, but instead of creating a new row at the end of the sheet find the original line and replace the data from B to U in whatever row it was originally in.
I know it's possible, I just don't know how.
'Copy Ranges Variable
Dim c As Variant
'Paste Ranges Variable
Dim p As Range
'Setting Sheet
Set wsInt = Sheets("Form")
Set wsNDA = Sheets("Data")
Set p = wsInt.Range("A14")
With wsInt
c = Array(.Range("B11"))
End With
For i = LBound(c) To UBound(c)
p(i + 1).Value = c(i).Value
Next
With wsNDA
Dim Lastrow As Long
Lastrow = .Range("B" & Rows.Count).End(xlUp).Row + 1
wsInt.Rows("14").Copy
With .Rows(Lastrow)
.PasteSpecial Paste:=xlPasteFormats
.PasteSpecial Paste:=xlPasteValues
.Interior.Pattern = xlNone
End With
With .Range("A" & Lastrow)
If Lastrow = 3 Then
.Value = 1
Else
.Value = Val(wsNDA.Range("A" & Lastrow - 1).Value) + 1
End If
.NumberFormat = "0#######"
End With
End With
End Sub
I found this code:
Sub CopyTest()
Dim selrow As Range, rngToCopy As Range
With Worksheets("PD DB")
Set selrow = .Range("B:B").Find(.Range("BA1").Value)
'find the cell containing the value
Set rngToCopy = Union(selrow.Offset(0, 9), selrow.Offset(0, 12))
'use offset to define the ranges to be copied
rngToCopy.Copy Destination:=Worksheets("Edit Sheet").Range("B50")
'copy and paste (without Select)
End With
End Sub
As far as I can tell this will do what I want mostly, but I can't seem to figure out where to break it up to add it where I need to to make it work the way I want it to.
What I can tell is this, it will copy and paste, but I want to make sure it will paste the data into row it finds, and not overwrite the number of said row.
Can someone help make that possible with the two scripts I have here?
Not tested, but should get you started. I added a 3rd sheet (shtMap) to hold the mmapping between the cell addresses on your form and the column numbers on the "Data" sheet. Useful to name your sheets directly in the VB editor: select the sheet and set the name in the property grid.
*EDIT:*If you want to trigger the transfer on selecting a record id from a list in Range AG3 then place this code in the code module for that worksheet:
Private Sub Worksheet_Change(ByVal Target As Range)
Static bProcessing As Boolean
Dim rng As Range
If bProcessing Then Exit Sub
Set rng = Target.Cells(1)
If Not Application.Intersect(rng, Me.Range("AG3")) Is Nothing Then
bProcessing = True
'this is where you call your macro to transfer the record
bProcessing = False
End If
End Sub
You could use something like this for the transfer:
Public Enum XferDirection
ToForm = 1
ToDataSheet = 2
End Enum
Sub FetchRecord()
TransferData XferDirection.ToForm
End Sub
Sub SaveRecord()
TransferData XferDirection.ToDataSheet
End Sub
Sub TransferData(Direction As XferDirection)
Dim rngMap As Range, rw As Range, f As Range, dataCell As Range
Dim formCell As Range, dataCol As Long, dataRow As Long
Dim sId As String
sId = shtForm.Range("AG3").Value
Set f = shtData.Columns(1).Find(sId, LookIn:=xlValues, lookat:=xlWhole)
If Not f Is Nothing Then
dataRow = f.Row
Else
'what do you want to do here?
' record doesn't exist on data sheet
MsgBox "Record '" & sId & "' not found on '" & shtForm.Name & "' !"
Exit Sub
End If
Set rngMap = shtMap.Range("A2:B10")
For Each rw In rngMap.Rows
'the cell on the edit form
Set formCell = shtForm.Range(rw.Cells(1).Value)
'column # on datasheet
Set dataCell = shtData.Cells(dataRow, rw.Cells(2).Value)
If Direction = XferDirection.ToDataSheet Then
dataCell.Value = formCell.Value
Else
formCell.Value = dataCell.Value
End If
Next rw
End Sub
Matt, there are two approaches I would take. The first is use find(), which returns a range object, then append ".row" so that you'll be able to modify the row on Sheet2 (wsNDA, I think). You may want to test that find() doesn't return Nothing.
Dim foundRow as Long
Dim foundRng as Range
set foundRng = wsNDA.find(wsInt.Range("B11").Value, ...)
If Not foundRng is Nothing Then
foundRow = foundRng.row
End If
'method without check: foundRow = wsNDA.find(wsInt.Range("B11").Value, ...).Row
The other is to use a Dictionary object. I'm not sure what you'd want for the key, but the item could be the row on the data sheet. When you make the change to what's on the form, check against the key and grab its item (the corresponding row) to determine where you need to replace the values.