Moving Rows to another sheet in a workbook - excel

I need Help!
I am not well versed in VBA or Macros but i cannot find any other way to accomplish what i need to do without using it.
I have a sheet which i will be using to track Purchase orders, and what i need to do is; when i have a row in sheet 1 (Purchase Orders) which has been recieved i.e. the date of receipt has been recorded in column H i need for the entire row to be cut and pasted into sheet 2 (Received orders).
The header takes up the first 7 rows the rows, so i need the macro to look at rows 8-54. Once the received items are removed from sheet 1, i need the row to also be deleted or preferably for the list to be sorted by column A moving the now empty row which has been cut from open for a future entry.
Any help would be greatly appreciated.

The "Record Macro" feature should be enough to do the task you describe.. In Excel 2007, go to the Developer tab in the Ribbon, and select "Record Macro", and perform exactly the steps you are describing. It will record the equivalent VBA code, which you can then execute - or tweak/modify.

I tested this out, here's one way to do it:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
Dim receivedDate As Range, nextOpen As Range, isect As Range
Set receivedDate = Sheet1.Range("H8:H54")
Set isect = Application.Intersect(Target, receivedDate)
If Not (isect Is Nothing) And IsDate(Target) = True Then
Set nextOpen = Sheet2.Range("A1").End(xlDown).Offset(1, 0)
Target.EntireRow.Copy Destination:=nextOpen.EntireRow
Target.EntireRow.Delete
End If
Application.EnableEvents = True
End Sub
This would be pasted into the Sheet1 code. Any time a cell is changed on sheet1, the code checks to see if it's in the critical range that you specified. (H8:H54) If it is, it then checks to see if it's a date. If it is, it then copies the entire row, puts it in the next open row on Sheet2, and deletes the original row. The cells below it will get shifted up so there are no gaps.
Since the code functions on a cell changing event, it disables "Application.EnableEvents" in order to avoid a loop of changing a cell to call an event which changes a cell to call an event... etc.

Related

Mirror cells from one sheet to another within the same workbook with special conditions

What are you trying to accomplish?
I'm trying to mirror the contents of a row of respective cells from one sheet to another. However, the caveat here are: I'm restricted to MS Excel not Access - I can use modules, the initials in column B are to be used as the condition to populate the corresponding sheets. Like: Primary key in MS Access and finally the sheets should be populated in real time; nothing should have to be run.
Said spreadsheet attached here.
What have you tried so far?
a. Well, I tried the =Value(x) and =Grand Budget!A(x) formulas. I setup the corresponding initials worksheets with the respective initials in the main sheet so for example: on sheet "Grand Budget" all NA initials and data in the corresponding row i.e. Description, Vendor and Amount will be mirrored on worksheet "NA" It works great until the third caveat is unfulfilled: it doesn't work in real time because I cannot predict what the next initial will be so I can't setup the next cell with a formula.
b. I also tried filtering the "Grand Budget" sheet by initials in column B, selecting the needed row data, named it and imported the named table to the corresponding initial worksheet. Source.
What do you have in mind - conceptually?
I'm thinking, it's time for modules or if someone knows a hidden excel formula, lay it on me. all I have right is an if statement in c++ in my mind: if(current_cell == desired_initial) {populate()};
I'm willing to aid in interpreting anything that may have been transposed incorrectly.
#peter
update on progress, I require assistance on how to populate the respective sheets. thank you!
Option Explicit
' Create a new sheet for new initials.
Sub CreateNewSheet(Initials As String)
'Checks whether a sheet with the name "Initials" exists
'Creates a new sheet if it doesn't exist yet.
If SheetExists("Initials") Then
MsgBox "Yay! the sheet exists"
Else
MsgBox "Boo! the sheet doesn't exist; I shall create a new one!"
'Creates a new sheet if it doesn't exist yet.
CreateSheet (Initials)
End If
End Sub
Function SheetExists(Initials As String)
On Error GoTo no:
WorksheetName = Worksheets(Initials).Name
SheetExists = True
Exit Function
no:
SheetExists = False
End Function
Private Sub CreateSheet(Initials)
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets.Add(After:= _
ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
ws.Name = Initials
End Sub
Private Sub sbClearEntireSheetOnlyData()
Sheets("Initials").Cells.ClearContents
End Sub
Private Sub MatchCase(Initials)
Dim x As Integer
Application.ScreenUpdating = False
' Set numrows = number of rows of data.
NumRows = Range("A3", Range("A3").End(xlDown)).Rows.Count
' Select cell a3.
Range("A3").Select
' Establish "For" loop to loop "numrows" number of times.
For x = 1 To NumRows
' Insert your code here.
' Selects cell down 1 row from active cell.
ActiveCell.Offset(1, 0).Select
Next
Application.ScreenUpdating = True
End Sub
Apparently there is no way to uniquely identify the rows on the Grand Budget sheet, we only know the sheet on which the row should go.
So if you really need to do this Real Time, I'm afraid you'll have to repopulate the entire user-sheet whenever there is a change anywhere in columns C-E of the budget sheet. And if there's a change in column B, you'll have to completely repopulate 2 user-sheets...
That tends to be a very error-prone process, so it's probably best to completely repopulate all user-sheets ...
My advice would be to ask your client to change the requirements... For instance, ask them if it's okay to have some Recalculate button to start your process.
If your client really doesn't want to use a button, you could ask if it's okay if your macro (which repopulates all user-sheets) starts automatically whenever you open the workbook and whenever you leave the Grand Budget sheet (which in effect also is the only input sheet).
By the way: What do you want to happen if they put nonexistent initials in column B?
Update: "I just spoke with said client, and i quote: "do what you must!" I like the recalculate button idea, please do pitch it to me!" – Nana Amponsah
If you don't have much experience with vba, it might be best to start with the second part: Create a new sheet for new initials.
Option Explicit
Sub CreateNewSheet(Initials As String)
'Checks whether a sheet with the name "Initials" exists
'Creates a new sheet if it doesn't exist yet.
'*** Your code goes here ***
End Sub
Please Note: Before you start, you should make a backup of the original workbook.
The first part of this page tells you how to make a module for your program.
And you might have a look at:
https://superuser.com/questions/1041635/how-can-i-tell-if-sheet-a-exists-in-a-workbook
How to Add a Named Sheet at the end of all excel sheets

Receipt printing - how to not show zero value rows

I am setting up a receipt printout from Excel 2010. I have multiple items on the worksheet and can print everything ok.
The receipt is to be printed in a busy environment and as such we just want the operators to enter the numbers and press CTRL+P.
Not all the items on the receipt will be used:
Item 1 10:00
Item 2 0.00 <--- This is an example of the row I do not want to print
Item 3 10.00
Total 20.00
The number of items could increase over time so the solution must be able to include the entire print range. Use of the hide function is not an option as it takes to long.
The solution must require no action by the user as they are not 'computer people'.
All cells are locked except those which require data to be entered to minimise input errors. i.e. VAT calculations
I had tried a VB routine but with no luck, hence the question.
EDIT: The VB I had written was-
Private Sub Workbook_BeforePrint(Cancel As Boolean)
Dim RngCol As Range
Dim i As Range
Set RngCol = Range("B1", Range("B" & Rows.Count). _
End(xlUp).Address)
For Each i In RngCol
If i.Value = 0 Then
i.EntireRow.Hidden = True
End If
Next i End Sub
I have tried Jeeped's suggestion but some how the page size has now changed - won't change back either?
Although Jeeped's suggestion has done what I wanted it is now ignoring the header which is needed although I can move the info to the main sheet.
Use a conditional format rule. I always use rules based on formulas like =NOT($D1) to cover columns A:E depending on the value in column D but any of the others will do if you can determine criteria that equals zero. When you decide on how you want to handle the criteria, click Format and go to the Number tab. Choose Custom from the list down teh left and use ;;; (three semi-colons) for the Type:.
Click OK to accept the format and then OK to create the rule. Nothing in A:E will be visible if there is a blank or 0 in column D.
Alternate AutoFilter Method:
The individual worksheets do not have any standard events to do with printing but the workbook has a BeforePrint Event.
Go the workbook's VBE and locate ThisWorkbook in the Project Explorer then double-click it. Paste the following into the new pane on the right titled something like ThisWorkbook (Code).
Option Explicit
Private Sub Workbook_BeforePrint(Cancel As Boolean)
Cancel = False
With Worksheets("Sheet2")
If .AutoFilterMode Then .AutoFilterMode = False
With .Range(.Cells(1, 2), .Cells(Rows.Count, 2).End(xlUp))
.AutoFilter Field:=1, VisibleDropDown:=False, _
Criteria1:="<>0.00", Operator:=xlAnd, Criteria2:="<>"
End With
End With
End Sub
Edit to suit the actual column that holds the numbers. I've used column B. Note that the AutoFilter requires a header row.
Tap Alt+Q to return to your worksheet. Any method of printing the page will result in the AutoFilter Method being applied to column B and hiding any blanks or zeroes (in the form of 0.00) in that column.
Before:        
After:    
As you can see from the sample images, printing to a .PDF filters the code column. I've also chosen not to display the little drop-down arrow normally associated with an AutoFilter.
You can unhide the rows with conventional unhide commands, clear the filter or just turn the autofilter off to get the rows back.
This latter method is a bit more involved but it gets rid of (aka hides or filters out) the undesired rows rather than simply not displaying the text in them. If need be, the worksheet could be unprotected for the duration of the print cycle.

VBA Code to enter formula in column b when column a is populated

I have a spreadsheet with a tab for each month. When a customer account number is entered into column a, I want a vlookup formula to be entered into column b, directly next to the cell in column a where the customer number was entered.
I have already set the sheets up with the vlookup formulas entered into the adjacent cells, but the sheet has become so big that the program has started to lag when the user enters data in column a. Now I am trying to reduce the size of the spreadsheet by setting up a vba code to enter this vlookup only when the cell in column a actually has data in it.
I have even tried creating a macro that will do this, and it works great, except my co-workers who use this sheet are VERY basic computer users, and it complicates things if they have to "do" anything to make the formula run.
You can use the worksheet's _Change event handler to do things, based on changes in the worksheet.
Sub Worksheet_Change(ByVal Target as Range)
'Prevent infinite loops by disabling event procedures
Application.EnableEvents = False
'Make sure that at least one cell in selection is in column A:
If Not Intersect(Target, Range("A:A")) Is Nothing Then Call MyMacro(Target)
'Turn the event procedures back on
Application.EnableEvents = True
End Sub
In any module, put the sub that will actually do the dirty-work. This is a preference of mine, rathr than trying to cram everything in to the _Change event handler, I simply parse the Target and hand it off to the appropriate subroutine.
Sub MyMacro(rng as Range)
Dim cl as Range
For each cl in rng.Cells
'## Make sure we're dealing with column A only:
If cl.Column = 1 Then
'## Insert a formula in the adjacent cell (column B)
cl.Offset(0,1).Formula = "=Vlookup(..."
End If
Next
End Sub

Auto populate new sheet with data

I tried looking at other similiar questions and solutions but as an Excel beginner I couldn't quite figure it out.
So I have the following macro:
Sub Worksheet_Change(ByVal Target As Range)
Dim wsNew As Worksheet
If Target.Cells.Count > 1 Or IsEmpty(Target) Then Exit Sub
On Error Resume Next
If Not Intersect(Target, Range("B46:B99")) Is Nothing Then
ThisWorkbook.Sheets("LT").Copy _
After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
End If
End Sub
It opens a new sheet in the same workbook and I'd need to auto populate certain cells with data from the main sheet. Main sheet: http://i.imgur.com/RJe44hQ.jpg new sheet: http://i.imgur.com/eatbg6j.jpg . The cells I need copied are in red.
Thanks in advance for any help! Really new to all this..
Since you don't specify which value(s) you need to pull from the main sheet I can't get too specific, but in general there are three approaches to take.
1) If the data is in contiguous range(s) of cells on both sheets, you can just copy the data from the main sheet after creating the new sheet, and then paste the values to the correct target range
2) If the data isn't contiguous on both sheets, then your next best option would be to have the value for each target cell set based on the value of the corresponding cell on the main page. Ex: To set A2 on Sheet2 to the value of B4 on Sheet1 you would use Worksheets("Sheet2").Range("A2").value = Worksheets("Sheet1").Range("B4").value
3) This one also works if the data isn't contiguous, but gets to be troublesome if there are more than ~5 values to copy. You can create an appropriate variable (string for text, long/int for numbers, etc.), set that before creating the new sheet, and then use them to set the appropriate cells once the new sheet is created.

Excel sheets dependant on / mirroring each other

Let's say I have three sheets in Excel. Sheet 1 is the Master sheet, sheets 2 and 3 contain different sets of information with the same headers that feed into the table in the master sheet. Is there a way to make it such that I could edit information in sheet 1 and sheet 2 will change AND vice versa so I can edit info in sheet 2 that will update the master sheet?
You could solve it by having Vlookup-formulas in your Master sheet. That way, if you change anything in sheet 2 and 3 the Master will automatically be updated.
If the user changes anything in the Master sheet, you will have to build logic in VBA on that. One way to go is to format the Master sheet so that there is something that helps the VBA know what the formula should be in the edited cell, and also to know from where the data should come. Loosely one could set up the Master sheet like this:
Row 1 is hidden and contains the template formulas
Row 2 is hidden and is completely empty (this will make less problems with filtering)
Row 3 contains headers
Row 4 and down contains the data, using the formulas define in row 1
Add the Change event on the Master sheet, that sees if the changed cell was one with a formula. If so, it will examine the template formula to identify from where the data should come. Then it will update that cell in Sheet 2 or 3 with the new value that is entered in the Master sheet. After this, it will overwrite the value manually entered in the Master sheet with the formula from the template row.
The big job here is to write a parser that understands from which cell the vlookup will get it's value.
One thing that I overlooked is that the CHANGE event is triggered only ONCE if the user pastes several cells in one go. The TARGET will then contain several rows or columns.
So this is some kind of skeleton using the above idea...
Option Explicit
Dim ChangeEventDisabled As Boolean 'Flag for disabling the Change event
Public Sub Disable_ChangeEvent()
ChangeEventDisabled = True
End Sub
Public Sub Enable_ChangeEvent()
ChangeEventDisabled = False
End Sub
Sub Worksheet_Change(ByVal Target As Range)
Dim updatedValue As Variant
Dim SourceCell As Range
'While the MasterSHeet is populated intially, we don't want this event to do anything
If ChangeEventDisabled Then
'There are chenges being done in teh sheet that should not trigger updates of the source-sheets.
Else
'Only run the code if it was a data-cell that was changed
If Target.Row > 3 Then
'We are in the rows containg data
'Did the changed cell contain a Vlookup formula before the user changed the cells value?
If UCase(Cells(1, Target.Column).Formula) Like "=VLOOKUP(*" Then
'A vlookup normally populates this cell.
'To know from where the data normally comes, I will need to put back the formula in the changed cell.
'So, first save the new value that we will write in the source cell
updatedValue = Target.Value
'Insert the formula again in the cell
'As we will now CHANGE a cell in the Masterr sheet, a Change event will trigger. Disable it temporarily
Disable_ChangeEvent
Cells(1, Target.Column).Copy Destination:=Target
Enable_ChangeEvent
'Find out from which cell the data is being fetched by the Vlookup
Set SourceCell = MyMagicParsing(Target)
'Update the source-cell with the new value
SourceCell.Value = updatedValue
End If
End If
End If
End Sub
Function GetSourceCell(Target As Range) As Range
'This function should decipher the formula in the cell Target, and figure out from where
'the data is actually coming. It shoudl return the range which is the source of the data.
'As I dont know how to do that quickly, I just hardcode the cell that is the source.
GetSourceCell = Worksheets("Sheet2").Cells(67, 3)
End Function

Resources