I created a macro in my excel sheet
The aim of the macro is to copy the cells in one column, one by one (L1,L2...), into a specific cell (A1). then after the calculations are done, copy the value from another cell E2, to the column next to L, meaning to M1, M2...
i couldn't know how to loop these steps to all the cells in the column.
Sub Checking_Frequences()
'
' Checking_Frequences Macro
'
'
Range("L1").Select
Selection.Copy
Range("A1").Select
ActiveSheet.Paste
Range("E2").Select
Application.CutCopyMode = False
Selection.Copy
Range("M1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("L2").Select
Application.CutCopyMode = False
Selection.Copy
Range("A1").Select
ActiveSheet.Paste
Range("E2").Select
Application.CutCopyMode = False
Selection.Copy
Range("M2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
is there a way to add a delay, so that excel finish calculations before copying the result from E2?
any advice?
regards
Your workbook can do with a little organisational upgrading. I may not have done it the way you best like but I think the code below will let you take a big step forward. Install it in a standard code module and run only the procedure WriteArrays. Take time to understand how it works first.
Sub WriteArrays()
' 043
' number of results wanted from each Base
Const Iterations As Integer = 5 ' adjust to suit
Const TgtTab As String = "Sheet3" ' Output tab (change to suit)
Const TgtRow As Long = 2 ' modify to suit
Const TgtClm As Long = 4 ' first output column (modify to suit)
Dim Src As Variant ' array of source Base numbers
Dim R As Long ' SrcRng row counter
Dim WsTgt As Worksheet ' Target worksheet (for output)
Dim Arr As Variant ' value to write to sheet
Dim Operand As Double ' calculated by a formula
Dim i As Long ' loop counter
Operand = 2 ^ (1 / 12) ' = 1.0594630943593 (adjust to suit)
With Worksheets("Frequencies")
' set the range L1:L(last used row) - modify to suit
' read all values into an array
Src = .Range(.Cells(1, "L"), .Cells(.Rows.Count, "L").End(xlUp)).Value
End With
Set WsTgt = Worksheets(TgtTab)
For R = LBound(Src) To UBound(Src)
Arr = BaseArray(Src(R, 1), Operand, Iterations)
With WsTgt.Cells(TgtRow, TgtClm - 1 + R).Resize(UBound(Arr))
.Value = Application.Transpose(Arr)
.NumberFormat = "0.00"
End With
' If R = 5 Then Exit For
Next R
End Sub
Private Function BaseArray(ByVal Base As Double, _
ByVal Operand As Double, _
ByVal Iterations As Integer) As Variant
' 043
Dim Fun As Variant ' function return value
Dim i As Integer
ReDim Fun(1 To Iterations)
For i = LBound(Fun) To UBound(Fun)
Fun(i) = Base
Base = Round(Base * Operand, 2)
Next i
BaseArray = Fun
End Function
There are 4 constants at the top of the code which you will have to set. The last 3 deal with the output. You asked for output in column M on the same sheet. But this code will add 235 columns. So I thought it better to start a new sheet. You can easily run the code multiple times with different parameters and output the results on different sheets. But they must exist before the code is run.
Const Iterations specifies how many rows there will be in each column. You seem to want 50. I tested with only 5. Modify this constant to suit your needs.
A little further down there is the Operand which is the formula taken from your cell C1. It can be changed.
Of course, the tab Frequencies must exist and it must have numbers in column L. You can start from row 2 instead of 1. But if you want to limit the output you may like to avail yourself of the method I used, here: If R = 5 Then Exit For (at the end of the Next ../.. For loop). It just curtails the loop after 5 numbers from the list, if you enable the line by removing the leading apostrophe.
I wish you the best of luck with your venture :-)
Related
i need a simple vba code. I hope someone can help me.
So, I want to copy the range B2:E6 and leave some cells marked with a special condition. I created a rule in cells A2:A6 with the value Y / X. In the end, I want to paste the value B2:E6 in the range F9:I13 only if the value is Y.
I am attaching the following image to make it easier for you to understand.
Any help will be great. And sorry my english is bad.
Maybe this can get you started
Sub Macro1()
Dest = 8
For Row = 1 To 6
If Cells(Row, 1) <> "x" Then
Range(Cells(Row, 2), Cells(Row, 5)).Select
Selection.Copy
Cells(Dest, 6).Select
ActiveSheet.Paste
End If
Dest = Dest + 1
Next Row
End Sub
I recommend that you first define your working worksheet, if the CommandButton1 button code linked to the CommandButton1_Click() event, showen in your code, is not associated with your working sheet (Sheet9). Otherwise, the code will be executed on another Sheet than Sheet9, on which you want the conditions to be fulfilled.
So, I suggest this code, that formats also the target table "(F8:I13)":
Private Sub CommandButton1_Click()
Dim myWorkingSheet As Worksheet
Dim Working_Range As Range, Target_Range As Range
Dim Line_to_Read As Double, Table_Shift As Double
Set myWorkingSheet = Sheets("Sheet9")
myWorkingSheet.Activate
' Copy the header table
myWorkingSheet.Range("B1:E1").Copy Range("F8")
Application.CutCopyMode = False
' Copy the format of the table
myWorkingSheet.Range("B1:E6").Copy
myWorkingSheet.Range("F8").PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
' Copy table if current cell in column A = "y"
Set Working_Range = myWorkingSheet.Range("A2:A6")
Line_to_Read = 2
Table_Shift = 7 'To start at F9 cell
For Each wr In Working_Range
If wr = "y" Then
myWorkingSheet.Range(Cells(Line_to_Read, 2), Cells(Line_to_Read, 5)).Copy myWorkingSheet.Range(Cells(Line_to_Read + Table_Shift, 6), Cells(Line_to_Read + Table_Shift, 10))
End If
Line_to_Read = Line_to_Read + 1
Next
' To point the cursor at the first cell.
myWorkingSheet.Cells(1, 1).Select
End Sub
To avoid the repetition of myWorkingSheet in the you use With clause and End With.
This is probably a really easy thing that I am screwing up. I am working on a school project Creating an Inventory sheet.
My "Inventory" sheet has a bunch of product info on it.
My "Add Inventory" Sheet is set up with a VLOOKUP so when I scan my bar code it displays the row of information from the "Inventory sheet"
I made a macro button and recorded a Macro to try to edit the available inventory by clicking the button.
This is what I recorded.(the original I slaughtered trying to edit it but this should be the same)
Sub Macro7()
'
' Macro7 Macro
'
'
Sheets("Add Inventory").Select
Range("B5").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Inventory").Select
Cells.Find(What:="764666143326", After:=ActiveCell, LookIn:=xlFormulas2, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
Range("K15").Select
Sheets("Add Inventory").Select
Range("K13").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Inventory").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("L15").Select
End Sub
So my problem is the macro records the What:="764666143326" for the search with the bar code I was using for a sample. I need it to use the new bar code I scan on the next run. So I need it as a variable or to refence a cell. So I believe I need to set a Dim and a Range but have tried many times and watched a ton of videos with no success. I normally only use the record Macro button and don't not edit the VBA code. Please Help Me!!
EDIT:
Everying on this sheet is filled with VLOOKUP or a formula, except the yellow Cell B5, I scan the bar code into that cell.
Add Inventory sheet
This is the page I want to edit with the Macro/VBA. I want it to search column C for the Bar code number I scanned into the "Add Inventory" sheet (which will change depending on what I am adding) and when it finds the matching bar code I want it to edit the "Quantity in Stock" or column K for that row of the matching bar code.
Inventoy sheet
My problem is the macro I recorded saves what ever barcode I used for it not the cell as a variable.
Edit # 2
I think this show closer to what I am trying to do
Sub Macro7()
'
' Macro7 Macro
'
'
Sheets("Add Inventory").Select
Range("K13").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Inventory").Select
Cells.Find(What:=Range("A1"), After:=ActiveCell, LookIn:=xlFormulas2, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate.Offset(0, 8).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Add Inventory").Select
Range("B5").Select
End Sub
For this one I made Inventory cell A1 = ='Add Inventory'!B5
Also My bar codes are 12 digits.
Update Inventory
Option Explicit
Sub addNewQuantity()
' Write lookup value (Bar Code) to a variable.
Dim lValue As Long: lValue = Range("B5").Value
' Define range (to look for Bar Code).
With ThisWorkbook.Worksheets("Inventory")
Dim fCell As Range: Set fCell = .Range("C4")
Dim lCell As Range: lCell = .Range(.Rows.Count, fCell.Column).End(xlUp)
Dim rg As Range: Set rg = .Range(fCell, lCell)
End With
' Attempt to find the index (row) of a match.
Dim cIndex As Variant: cIndex = Application.Match(lValue, rg, 0)
If IsNumeric(cIndex) Then
' Write new value to column 'K' (8 cells to the right from column 'C').
rg.Cells(cIndex).Offset(, 8).Value = Range("K13").Value
MsgBox "Bar Code ID '" & lValue & "' updated.", vbInformation, "Success"
Else
MsgBox "Bar Code ID '" & lValue & "' not found.", vbCritical, "Failure"
End If
End Sub
Unfortunately I think there is a bigger problem with this method recorded by the macro recorder - this code will always select range "K15" regardless of what you search for.
I recommend you do not use the macro recorder, among other reasons it often creates code full of semantic errors - i.e. it works and it does does exactly what you tell it to do, which may not be the same as what you want it to do! As in the example above.
I would try something like this (you will need to check that the worksheets, ranges and column numbers in the code below are correct for your project):
First we declare and assign a worksheet object, referring to your Inventory worksheet:
dim ws as worksheet
set ws = Sheets("Inventory")
Then we need to loop through every row on this worksheet and if the value in the barcode column matches a given search parameter, increase the value in the stock level column on that row, by the value of another cell on another sheet.
For this we will need a counter for the loop:
dim counter as integer
the search parameter:
dim searchParam as variant
searchParam = Sheets("Add Inventory").Range("B5").value
and the new value we want added to the current stock level:
dim newValue as variant
newValue = Sheets("Add Inventory").Range("K13").value
we need to tell Excel which column number to search in and which to change, I assumed you are adding stock to the inventory. You will need to change the column numbers below to suit your project
Dim barcodeColumnNumber As integer
Dim stockColumnNumber As integer
barcodeColumnNumber = 1
stockColumnNumber = 2
Now we add the loop
For counter = 1 To ws.UsedRange.Rows.Count
if ws.Cells(counter, barcodeColumnNumber) = searchParam then
ws.Cells(counter, stockColumnNumber) = ws.Cells(counter, stockColumnNumber) + newValue
End If
Next counter
I have an EXTREMELY large data set in excel with varying data sets (some have 12 lines and some with 18, etc) that are currently in rows that needs to be transposed to columns. All the groupings are separated by a empty/blank line.
I started the VBA to transpose this it but dont know how to include/look at the blank line and loop it to the end of each sheet. Any ideas/suggestions?
Range("F1:F12").Select
Selection.Copy
Sheets("Sheet4").Select
Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Sheets("Sheet3").Select
Range("F14:F27").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet4").Select
Range("A2").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Range("G14").Select
Avoid using Select statements at all costs and when possible, use the Array data structure to process data. Processing data in Arrays is much faster than reading/writing from the worksheet. The Procedure below should do what you want. Note that although it's not ideal to use ReDim Preserve in a loop, however, I have used it for row counts of over 100,000 with no issue. Point being, 13,000 rows should be no problem.
Sub Transpose()
Dim Data_Array
Dim OutPut_Array()
Dim LR As Long, Counter As Long, LR2 As Long
Dim i As Long
Application.ScreenUpdating = False
'Find the last row of your data in Sheet3 Column A
'I added 1 so that the conditional statement below
'doesn't exclude the last row of data
With Sheets("Sheet3")
LR = .Cells(Rows.Count, "A").End(xlUp).Row + 1
Data_Array = .Range("A1:A" & LR).Value2
End With
'See explanation in the edit section below
On Error Resume Next
For i = LBound(Data_Array, 1) To UBound(Data_Array, 1)
'if the cell is not blank then increase the counter by one
'and for each non blank cell in the Data_Array,
'add it to the OutPut_Array
'If its not blank then output the prepopulated OutPut_Array to Sheet4 and
'set the counter back to zero
If Trim(Data_Array(i, 1)) <> vbNullString Then
Counter = Counter + 1
ReDim Preserve OutPut_Array(1 To 1, 1 To Counter)
OutPut_Array(1, Counter) = Data_Array(i, 1)
Else
With Sheets("Sheet4")
LR2 = .Cells(Rows.Count, "A").End(xlUp).Row
.Range("A" & LR2 + 1).Resize(1, Counter).Value2 = OutPut_Array
End With
Counter = 0
End If
Next i
End Sub
Test Data:
Result:
This could also be done with a nested dictionary however in this case it would need to be assisted by array to create a one to many relationship using conditional statements, and then transposing the dictionary, but I am still trying to perfect that method so I went with the above, lol. Hope this is helpful.
Edit: Added On Error Resume Next as per OP's request for the procedure to work even if there is more than one blank between the rows of data. In this case On Error Resume Next avoids the Run-time error '1004' Application-defined or Object Defined Error associated with the Range.Resize property. The error is thrown when the if statement is looking at occurences of a blank cells greater than 1. In the else portion of the statement, the counter variable would be equal to 0, thus causing the second dimension of the range to be 0 and throwing the error. If the cells in column A are truly blank as the OP suggests, then this is a valid method to trap the error. Also added the Trim() function to handle blank cells that may have spaces.
Try adapting this.
Sub x()
Dim r As Range
application.screenupdating=false
For Each r In Sheet1.Columns(1).SpecialCells(xlCellTypeConstants).Areas
r.Copy
Sheet2.Range("A" & Rows.Count).End(xlUp)(2).PasteSpecial Transpose:=True
'Sheet2.Cells(1, Columns.Count).End(xlToLeft).Offset(, 1).PasteSpecial Transpose:=True
Next r
application.screenupdating=true
End Sub
I am having problems with getting a loop to run.
I have a Source1 spreadsheet with a list of values in Column A on the CC's tab. Each number is to be copied individually into Cell B1 on the Template tab of the Source2 spreadsheet.
Cell B1 triggers a consolidation of information (mainly indexed info) and displays it in a template - an aggregate picture of lots of background data. I then Copy A1:K71, and paste this into the Output tab of the Source1 spreadsheet.
I want to work down the list in Column A of the CC's tab, and append each output from the Source2 spreadsheet into the Output tab automatically.
I have the copy/paste working, but I am having problems with the loop.
Selection.Copy
Windows("Source2.xlsx").Activate
Range("B1").Select
ActiveSheet.Paste
Range("A1:K71").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Source1.xlsm").Activate
Sheets("Ouput").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
ActiveWindow.SelectedSheets.HPageBreaks.Add Before:=ActiveCell
#Andrew, after reading and re-reading your question, I don't think a loop of any kind is necessary. The macro-recorder results you gave above provide information about how you can solve this. I tested this by creating a Source1 Workbook with values placed in column A on a sheet labeled CC's. I also added a sheet labeled Output. Then, I opened a second Workbook with a sheet labeled Template. Here is the sub-procedure I used to produce the result I think you are describing above:
Sub AndrewProject()
' COMMENT: Declare variables used throughout this procedure
Dim InitialVals As Range
Dim OutputVals As Range
Dim FinalResults As Range
Dim FinalOutput As Range
Dim cell As Variant
' COMMENT: Set the range objects so they are easier to manipulate
Set InitialVals = Workbooks("Source1").Worksheets("CC's").Range("A2:A72")
Set OutputVals = Workbooks("Source2").Worksheets("Template").Range("B2:B72")
Set FinalResults = Workbooks("Source2").Worksheets("Template").Range("A2:K72")
Set FinalOutput = Workbooks("Source1").Worksheets("Output").Range("A2:K72")
' COMMENT: This line copies the values in Source1 Workbook and pastes them into Source2 Workbook
InitialVals.Copy
OutputVals.PasteSpecial xlPasteValues
' COMMENT: Additional code goes here to create the desired output. To simplify things, I put a
' function in Source2, column K that concatenates the string "Output" with InitialVals copied
' from Source1. To emulate your Source2 Template, I placed random values between 1 and 1000 in
' Cells A2:A72 and C2:J72.
' COMMENT: Copy the FinalResults from Source2 "Template" tab into the Source1 "Output" tab
FinalResults.Copy
FinalOutput.PasteSpecial xlPasteAll
End Sub
OK #Andrew...this has got to be my last attempt. I believe this answers your question.
Sub AutomateIt()
' Declare your variables
Dim cell As Range
Dim Src1CC As Range
Dim Src2Template As Range
Dim Src2Calcs As Range
Dim Src1Output As Range
Dim NextRow As Long
Dim count As Integer
' Set the ranges so they can be manipulated
Set Src1CC = Workbooks("Source1").Worksheets("CC").Range("A1")
Set Src2Template = Workbooks("Source2").Worksheets("Template").Range("B1")
Set Src2Calcs = Workbooks("Source2").Worksheets("Template").Range("A1:K72")
Set Src1Output = Workbooks("Source1").Worksheets("Output").Range("A1:K72")
Src2Template.ClearContents
count = 0
' Loop through all the cells and calculate stuff
For Each cell In Src1CC.Range(Src1CC, Src1CC.End(xlDown))
'Determine the next empty row (plus a space for readability)
NextRow = Cells(Rows.count, 1).End(xlUp).Row + 2
'Send a copy of the Src1CC cell value to the Src2Template
cell.Copy Src2Template
'Re-calculate A1:K72 based on cell value
Src2Calcs.Calculate
'Copy Src2Calcs results and paste to Source1 Output
Src2Calcs.Copy
Src1Output.PasteSpecial xlPasteValues
count = count + 1
MsgBox "You have pasted " & count & " results."
'Change Src1Output Range so that the next paste is the next blank row
'plus one additional row for readability.
Set Src1Output = Workbooks("Source1").Worksheets("Output").Range(Cells(NextRow, 1), Cells(NextRow, 11))
Next cell
End Sub
I have written the following code to copy and paste range w21:W1759 into range AD21:
Sub CommandButton1_Click()
Dim i As Integer, j As Integer
For j = 1 To Range("d7")
Range("d8") = j
'Calculate
Range("w21:W1759").Select
Selection.Copy
Range("AD21").Select
Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
Next j
End Sub
My data in range w21:W1759 is set to change (due to random sampling) on every click and I want the new data in this range to be copied and pasted to range "ae" (the adjacent column). Then on the next click to "af" and so on and so on. What code do I need to add to the above to achieve this?
Thanks very much for the help
This will depend somewhat on what is to the right of column AC. If column Ad is the first empty column then it is easy to copy to. Subsequent copying operations can use the same next-empty-column method to fill columns AE, AF, etc.
Sub CommandButton1_Click()
Dim i As Long, j As Long
With Worksheets("Sheet1")
For j = 1 To .Range("d7")
.Range("d8") = j
.Calculate
With .Range("w21:w1759")
.Parent.Cells(21, Columns.Count).End(xlToLeft).Offset(0, 1).Resize(.Rows.Count, .Columns.Count) = .Value
End With
Next j
End With
End Sub
I've altered your Copy, PasteSpecial Values method to be a direct value transfer. This is faster and does not involve the clipboard.