My task is to create a searchable database within Excel with an entry form. I need a macro to take the data from the entry form move to the database sheet offset the active cell down 1 row and copy the values only(not the formatting)
Every time I try to run the macro I get a run-time error in the code. I have no experience with VB or VBA; please tell me what is wrong with this.
Sheets("Database").Select 'Navigates to Database worksheet
If ActiveSheet.FilterMode Then
ActiveSheet.ShowAllData
End If 'Clears filters
Sheets("Entry Form").Select 'Navigates back to Entry Form worksheet
Range("E10:L10").Select ' select date, period, and data
Selection.Copy
Sheets("datatable").Select ' navigate to datatable tab
Range("A1").Select
Selection.End(xlDown).Select ' ctrl-down to last occupied row,
ActiveCell.Offset(1, 0).Select ' then one more to first blank row
Selection.PasteSpecial Paste:=xlPasteValues
'Pastes data as values only into the Database worksheet
Sheets("Entry Form").Select 'Navigates to Entry Form worksheet
Application.CutCopyMode = False 'clears copy data from clipboard
Range("E10, L10").Select
Selection.ClearContents 'Clears data from drop down selections
Range("E10").Select 'Returns selection back to Date entry box
It goes the very bottom of the next page and gives a 1004 error.
You need more than just a column label in A1 if you are going to use xlDown. There has to be at least one more value in column A or you will traverse to the bottom of the worksheet. It is usually better to look from the bottom of the worksheet upwards and then offset one row down.
With Sheets("Database") 'Primarily use Database worksheet
If .FilterMode Then .ShowAllData
With .Cells(Rows.Count, 1).End(xlUp).Offset(1, 0) 'look from bottom up then down 1 row
'direct value transfer is faster than Copy, Paste Special, Values
.Cells.Resize(1, 8) = Sheets("Entry Form").Range("E10:L10").Value
End With
End With
With Sheets("Entry Form") 'Primarily use Entry Form worksheet
.Range("E10:L10").ClearContents 'Clears data from drop down selections
.Range("E10").Select 'Returns selection back to Date entry box
End With
This makes use of the With ... End With statement to control which worksheet is receiving attention. See How to avoid using Select in Excel VBA macros for more methods on getting away from relying on select and activate to accomplish your goals.
Related
I have the following form:
When user clicks the "Submit Adjustment" button, I want the information in the yellow boxes (plus the date on that line) entered into the following table
Here's the code I'm using:
Sub LOG_CHG()
Sheets("ENTER CHG").Range("B8:I8").Copy
Sheets("CHANGE LOG").Cells(Rows.Count, "A").End(xlUp).Offset(1). _
PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
MsgBox ("Your adjustment has been logged.")
Range("C8:I8").Select
Selection.ClearContents
Range("C8").Select
End Sub
This is happening somewhat successfully, but sometimes it gets lost and pastes at the bottom of the table or in random places.
How can I make sure it pastes the information in the next available row?
Sheets("CHANGE LOG").Cells(Rows.Count, "A").End(xlUp).Offset(1)
This line means Excel is checking sheet "change log" from last Excel line in column A up until it finds any symbol in cell. And offset(1) means 1 row down. For example:
You have something written in A32(space, number or letter), but from A33 to A1000000+ row is nothing --> so your code will paste everything in A33.
In other words Select A1000000 and press Ctrl+UP.
As you are using a table on the log-sheet you can access it via the listobjectwhich is pretty easy to program against.
Public Sub log_chg()
Dim rgSource As Range
Set rgSource = ThisWorkbook.Worksheets("Enter chg").Range("B8:I8")
Dim loChangeLog As ListObject
Set loChangeLog = ThisWorkbook.Worksheets("Change log").ListObjects(1)
Dim lrTarget As ListRow
Set lrTarget = lo.ListRows.Add
lrTarget.Range.Value = rgSource.Value
End Sub
No need to check for the last row or anything.
ListRowis always appended to the end of the table.
As the ranges of the source and the target are of same size you can write the value like shown in the code.
What you should do before testing: delete all the empty rows of the log table.
I'm trying to create a macro to copy cells down an entire column of a table in hopes of acting as a 'refresh' in case those formulas were altered or replaced.
I have multiple tables in the same sheet so I can't select the table name because they constantly change.
What I'm thinking of is having a bottom row with a keyword that VBA can select down until they hit the keyword and select those cells to copy the formulas down.
The thing is that I have multiple tables and they would all have the bottom row of keywords.
When I recorded a macro, I have to Control+Shift+Down multiple times to account for missing rows which I imagine wouldn't always be the case. This is what scares me for this macro since sometimes a table would have no missing data so the xlDown function would select more data than it should.
Here is what I recorded:
Sub Macro9()
'
' Macro9 Macro
'
'
ActiveCell.Offset(3, 2).Range("A1").Select
Range(Selection, Selection.End(xlToLeft)).Select
Selection.Copy
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlDown)).Select
ActiveSheet.Paste
End Sub
Here is an example of the column I am trying to restore formulas on:
I want the formula below "Total Price" to fill down until it hits the word "Total". Note that formulas are hidden if there is no data elsewhere in the sheet.
There are multiple tables on this sheet so this would have to work in different sections of te same sheet.
If you have actual Tables/Listobjects then you could do something like this:
Sub FillDownFormulas()
Dim lo As ListObject, col As Range
For Each lo In ActiveSheet.ListObjects
For Each col In lo.DataBodyRange.Columns
If col.Cells(1).HasFormula Then 'first cell in column has a formula?
col.Formula = col.Cells(1).Formula 'fill formula to rest of column
End If
Next col 'next column
Next lo 'next table
End Sub
One of the most simple ways (for people that usually don't use VBA) is to get the number of the last row in your table. You can do that by counting values in table or with your own code by using a column that is always filled, like:
last_row = Range("B2").end(xldown).row
With last_row value you can fill your formula in ranges, like:
Range("C2").value = 'Your Formula here
Range("C2").AutoFill Destination:=Range("C2:C" & last_row)
You can do that to every column that you want.
I am new to VBA, I have to copy cell value from one sheet to another. The existing code was
'go to the team sheet and select col 3-5 on last row and copy
Sheets(strname).Activate
ActiveCell.Offset(0, -10).Select
Range(ActiveCell, Cells(ActiveCell.Row, ActiveCell.Column + 2)).Select
Selection.Copy
DoEvents
'select the col 2 on team line and paste
Sheets("dtl overview").Select
ActiveCell.Offset(0, -6).Select
ActiveSheet.paste Link:=True
DoEvents
The problem is , I have added one more column in the 'team' sheet. So the above copy script has to read one cell backward.
Say for example, the above code is reading the data from D,E & F cells. I dont know how...
I am looking for to change the above code to read the value from C,D&E.
Inputs are Welcome & Highly appreciable!
I don't know how you consistently copy from columns D:F using that code either.
What your code does is:
'Activate sheet indicated in the "strname" variable.
'"strName" must be set elsewhere in the code?
Sheets(strname).Activate
'When the sheet is activated a cell will already be selected on there.
'This will be whatever cell was active when the sheet was previously looked at.
'This could easily change if a user selects another cell.
'The "OFFSET" command looks at the same row and ten columns to the left of the ActiveCell.
'If the ActiveCell is not in at least column J (11th column) then this
'will throw an "Application defined or Object Defined error" as it will try and select
'a column before column A.
'The offset cell is then selected - hopefully it will be column D.
ActiveCell.Offset(0, -10).Select
'This will select a range from the ActiveCell plus 2 columns on the same row.
'Hopefully columns D:F
Range(ActiveCell, Cells(ActiveCell.Row, ActiveCell.Column + 2)).Select
'Copy the selection.
Selection.Copy
'Don't need this line unless other code you haven't included needs it.
DoEvents
'Select the "dtl overview" sheet.
Sheets("dtl overview").Select
'Again, whichever cell was last active on "dtl overview" and select the cell 6 columns to the left.
ActiveCell.Offset(0, -6).Select
'Paste a link to the original cells.
'So if you copied D4:F4 on the original sheet (which I'll call "Sheet1") then this will paste
'=Sheet1!D4 , =Sheet1!E4 and =Sheet1!F4
ActiveSheet.Paste Link:=True
'Definitely shouldn't need this now.
DoEvents
At the moment your code looks 10 columns to the left of whichever cell is currently active - so depends which cell you have selected when you run the code.
You don't say which row you want copying, so this code copies row 1 and pastes to cell D1.
Sub Test()
Dim strName As String
strName = "Sheet1"
'ThisWorkbook means the file containing this code.
Dim wrkSht As Worksheet
Set wrkSht = ThisWorkbook.Worksheets(strName)
'Cells(1,4) is row 1, column 4.
'Range(Cells, Cells) shows a start & end cell for the range.
With wrkSht
.Range(.Cells(1, 4), .Cells(1, 6)).Copy _
Destination:=ThisWorkbook.Worksheets("dtl overview").Cells(1, 4)
End With
End Sub
Further reading: With
I have a macro that is supposed to copy the format of a row and insert a new row with the same format.
Here is the macro code:
Sub Insertion_ligne_verrouillée()
'
' Insertion_ligne_verrouillée Macro
ActiveSheet.Unprotect
ActiveCell.Offset(-1, 0).EntireRow.Copy
Rows(ActiveCell.Row).Insert Shift:=xlDown
On Error Resume Next
Rows(ActiveCell.Row).SpecialCells(xlCellTypeConstants).ClearContents
ActiveSheet.Unprotect
'Application.CutCopyMode=False
End Sub
Now i am not the one that wrote the macro and honestly my VBA is quite rusty (also not that good in VBA either). The problem i am having is the user is using the macro by selecting a row and using ctrl+L.
It does copy and insert a row with the right format, however some rows afterward seem empty (all blank and no row number) so you have to select the row > right click > display, for it to display properly
Not sure what to look for
The following code makes a new row below the row you want to copy then copies the format of the row and paste into the new row.
Sub Insertion_ligne_verrouillée()
'Make a new row below active cell
ActiveCell.Offset(1).EntireRow.Insert Shift:=xlDown,
CopyOrigin:=xlFormatFromRightOrAbove
'Copy the active row
ActiveCell.EntireRow.Copy
'paste format into new row
ActiveCell.Offset(1).EntireRow.PasteSpecial xlPasteFormats
Application.CutCopyMode = False
End Sub
Below is just a macro I recorded myself which may or may not be helpful. Basically, I am trying to copy the number, name, and date from one sheet (Worksheet) then paste into a different spreasheet (Data Entry Form).
FYI, the number, name, and date goes from left to right on the ‘Worksheet’, and Each row of data (number, name , and date) needs to go into a separate ‘Data Entry Form’.
So I am looking for a macro that will use the data from “Worksheet” and place it into the ‘Data Entry Form’ while generating additional ‘Data Entry Forms’ (more worksheets) for each separate row of data.
The number of rows in the Worksheet can vary from 10-100 so having a macro would save me ample time of copying and pasting into new forms; even if the macro can only do one row of data at a time.
Sub Popsecform()
'
' Popsecform Macro
'
' Keyboard Shortcut: Ctrl+m
'
Selection.Copy
Windows("Data Entry form.xlsx").Activate
Range("F8").Select
ActiveSheet.Paste
Windows("Worksheet.xlsx").Activate
Range("C2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Data Entry form.xlsx").Activate
Range("F30").Select
ActiveSheet.Paste
Windows("Worksheet.xlsx").Activate
Range("D2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Data Entry form.xlsx").Activate
Range("F24").Select
ActiveSheet.Paste
End Sub
Edit
I am just trying to create a workbook that will be able to generate my Data Entry Form as an additional sheet to the workbook every time I add another row of Name, Number, and Date to the first Worksheet.
Row A goes to Data Entry Form 1 (Distinct cells)
Row B goes to Data Entry Form 2 (same distinct cells)
and so on