Loop by criteria - excel

Can anyone helps me please, I'm newbie to using macro :)
I want to loop my macro by criteria, ex : criteria 1 & 2
in this case I just define 2 criteria, and some case I have 20 criteria
So I want to filter criteria 1, and I copy some rows & column and make new file and save to specific folder and the name same with the criteria, and I want to repeat it with different criteria and different name file.
Filter I want to loop
This is my Code, I hope someone can help me,
Sub Converter()
Sheets("SHEET INPUT").Select
ActiveSheet.Range("$A$2:$AQ$4652").AutoFilter Field:=22, Criteria1:="<>"
ActiveSheet.Range("$A$2:$AQ$4652").AutoFilter Field:=5, Criteria1:="1"
Range("W2:AQ2").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Workbooks.Add
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Selection.Columns.AutoFit
Application.CutCopyMode = False
With Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlBottom
End With
Range("B1").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.NumberFormat = "m/d/yyyy"
Range("N1").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.NumberFormat = "m/d/yyyy"
Range("R1").Select
ActiveWorkbook.SaveAs Filename:="C:\Users\BJ900265\Documents\Z-Spam File\Converter Temap\PO 1.xlsx", _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
ActiveWindow.Close
End Sub
I've seen several tutorials and I can't found what I want

I would suggest not using excel filter but filtering in own loop while/for. I'm also newbie so this approach is based on low experience, but I can imagine it being easy to write. U can easily control number/name of criterias/WB then.

I can give you the whole idea of a loop. For the details you just have to put anything you wrote inside the loop.
You can use any kind of loop (Do-While/Do-Until/For) To this purpose. I would suggest For Loop:
First you have to count how many times your For Loop wants to be repeated, in this case it seems to be number of rows in your desired column (Criteria).To count number of rows in your desired column you can make a Range of Cells under your column header (Criteria) then Count number of this Range cells.
Let's say the column you want to count number of cells bellow is Trigger CPS 1, Then you can count the cells below it this way:
ActiveSheet.Range(Range("A3"),Range("A3").End(xlDown)).Cells.Count
So To this point you have your i value for your For Loop:
All you have to do is to put your Selecting, Copying and Pasting operations inside this loop.

Related

Excel 2013 VBA - fill a range of cells with data from another worksheet related to a certain key

my problem described best with an example.
I got a worksheet like the following
I want to fill the empty cells at the bottom automatically like a drill down feature based on the data in another worksheet which looks like the following
The key value to the data from the second worksheet is the project code. So we have to loop over the data in the second sheet, fetch row by row and insert into first worksheet starting in row 5 just beneath "Task Code".
Unfortunately I found no solutions anywhere or my search was not exact enough and the topmost answers did not match my needs.
Thanks in advance for any suggestions
you can use this VBA code below and assign the macro to a button:
First Worksheet Sample
Second worksheet Sample
Sheets("Sheet1").Select
Range("A5:C5").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.ClearContents
Dim searchValue As Integer
searchValue = Cells(2, 1).Value
Range("A2").Select
Selection.Copy
Sheets("Sheet2").Select
ActiveSheet.Range("A:A").AutoFilter Field:=1, Criteria1:=searchValue
Range("B2:D2").Select
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
Range("A5").Select
ActiveSheet.Paste
Sheets("Sheet2").Select
ActiveSheet.Range("$A$1:$D$7").AutoFilter Field:=1
Range("A10").Select
Application.CutCopyMode = False
ActiveCell.FormulaR1C1 = ""
Range("A11").Select
Sheets("Sheet1").Select
Range("A2").Select

Excel 2013 VBA select cell P for every row that has data in column A

Working on a function to put the filename in a specific column (P) of a file. I've got this running if I specify the cells to put the filename in (e.g. P1:P5).
However, I want to get this to run in the P column, but for all rows that have data in the A column.
I know I could do it for just the whole P column, but i dont want it to run on empty rows (they're of no use)
Code I have so far:
Sub Save_files()
Cells.Select
Selection.Copy
Workbooks.Add
ActiveSheet.Paste
Rows("1:3").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlUp
Range("P2").Select
ActiveCell.FormulaR1C1 = "=CELL(""filename"")"
Range("P2").Select
Selection.Copy
Range("p1:p5").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Range("D4").Select
End Sub
I want to replace Range("p1:p5").Select with something that selects every P cell that is on a row with data in A of the same row.
Things to note:
Column A will always have data
Columns B through to O may or may not have data
Thanks in advance!
I changed:
Range("p1:p5").Select
to:
LastRow = Cells(Rows.Count, "A").End(xlUp).Row
Range("p1:p" & LastRow).Select

VBA Macro: Paste underneath last cell in column with variable range

Title isn't the best so here a an overview.
I'm using VBA to copy select columns from one workbook to another, as what will be part of a larger automated program.
On the Workbook I am copying from, there are different sheets containing a "Stock Number" column. When pasting into my other workbook, I am trying to get these columns to merge into 1 single column (pasting below the last entry from the first sheet and so on).
Here is my current code:
Sub import_adam_article()
Windows( _
"copyfrom.xlsx" _
).Activate
Columns("F:G").Select
Selection.Copy
Windows("pasteinto.xlsx").Activate
Columns("A:A").Select
ActiveSheet.Paste
Windows( _
"copyfrom.xlsx" _
).Activate
Columns("N:N").Select
Application.CutCopyMode = False
Selection.Copy
Windows("pasteinto.xlsx").Activate
Columns("C:C").Select
ActiveSheet.Paste
Rows("1:1").Select
Selection.Delete Shift:=xlUp
NextRow = Range("A1").End(xlDown).Row + 1
Windows( _
"copyfrom.xlsx" _
).Activate
Columns("F:G").Select
Selection.Copy
Windows("pasteinto.xlsx").Activate
Range("A" & (NextRow)).Select
ActiveSheet.Paste
[A:C].Select
With Selection
.NumberFormat = "General"
.Value = .Value
End With
End Sub
The difficulty is that the amount of Stock Numbers will change every new file that comes through, so it needs to be able to adjust to varying amounts.
I can't seem to find a way to make it work and I've tried searching for answers elsewhere.
EDIT: The current issue with the code that it is selecting the next empty row to paste into, but only that cell, not a variable length down as required by the copyfrom column.

Formatting date columns as text using VBA - Question

The problem: the dates displayed in my excel files are not the actual dates entered into each cell. For example, I might visually see 04/18/2019 but when I click on the cell, it shows 04/18/2019 06:48:00PM. This becomes an issue when I run the macro I use to convert my xlsx file to txt. The txt file generated will show 04/19/2019 06:48:00PM in the date field rather than what I want, 04/18/2019.
The current fix I'm using is to insert columns next to the date columns, copy the date columns and paste values into the new inserted columns, and then deleting the inserted columns. This was accomplished through recording a macro (I'm a noob if you couldn't tell).
That rudimentary fix does actually work quite well at generating the output I need. Except one problem: if there are any blanks in the date columns, it pastes in 01/01/1900. Blanks in date columns is fairly common in the work I do so this is a major problem.
I tried adding this If in after the inserting/pasting values/deleting code:
'Fix Date format in columns A and C
'
Columns("B").Select
Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Columns("E").Select
Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Range("B1").Select
ActiveCell.FormulaR1C1 = "=TEXT(RC[-1],""mm"/"dd"/"yyyy"")"
Range("E1").Select
ActiveCell.FormulaR1C1 = "=TEXT(RC[-1],""mm"/"dd"/"yyyy"")"
Range("B1").Select
Selection.AutoFill Destination:=Range("B1:B" & EndRow)
Range("E1").Select
Selection.AutoFill Destination:=Range("E1:E" & EndRow)
Range("B1:B" & EndRow).Select
Selection.Copy
Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("E1:E" & EndRow).Select
Selection.Copy
Range("D1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Columns("E").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlToLeft
Columns("B").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlToLeft
If Range("A1:A") = "01/01/1900" Then ClearContents
'
But I get this error "Compile Error: Sub or Function not defined", with the word Range within the If statement highlighted. I don't understand why it isn't recognizing range since it is used just a few lines up without issue. I have to be doing something wrong but I'm lost. Any ideas?
PS - The If is just a means to an end as far as remedying the blanks, but I'm sure there's a better way to convert these date columns to text or to the date format I want. If you have any recommendations for some easier way to achieve the same results I am all ears.
Thanks guys I really appreciate it!
Range("A1:A")
That's a google-sheets reference for 'everything from A1 down to the last used cell in column A' not a VBA style. Either reference the entire column (e.g. Range("A:A")) or modify the end row with your EndRow var (e.g. Range("A1:A" & EndRow)).
The formating mask used in the VBA application of the TEXT formula seems wrong. When using a quote within a quoted string,double up the quote once every time it ix used. The TEXT formula returns a string (i.e. text); you do not need to attempt any further conversion.
ActiveCell.FormulaR1C1 = "=TEXT(RC[-1],""mm/dd/yyyy"")"
Both xlR1C1 and relative styled xlA1 formulas be applied to all cells at once. A Union of the target cells in columns B and E further expedites the formula insert.
Range("B1:B" & EndRow & ",E1:E" & EndRow).formular1c1 = "=TEXT(RC[-1],""mm/dd/yyyy"")"
You cannot directly compare a multiple cell range to a single value. Either loop through the cells or use a wide-range comparison like Range.Find, the worksheet's MATCH function or an AutoFilter to expose the matching cells as xlCellTypeVisible.
dim m as variant
m = application.match("01/01/1900", ActiveSheet.Range("A:A"), 0)
do while not iserror(m)
ActiveSheet.Cells(m, "A").clearcontents
m = application.match("01/01/1900", ActiveSheet.Range("A:A"), 0)
loop
If you've read down this far, the easiest method of stripping the date out of a date-time is Text-to-Columns. Simply discard anything after the 10th character (e.g. mm/dd/yyyy from mm/dd/yyyy hh:mm amp/pm).
With ActiveSheet.Columns("A")
.TextToColumns Destination:=.Cells(1), DataType:=xlFixedWidth, _
FieldInfo:=Array(Array(0, 1), Array(10, 9))
.NumberFormat = "mm/dd/yyyy"
End With
I would humbly suggest you take some time to investigate How to avoid using Select in Excel VBA. If you continue to develop VBA to make your Office applications more efficient, you should start using recommended methods as soon as possible.

Cut Paste data from excel sheet using Autofilter in Excel VBA

Current i have an excel with roughly 200000+ records and i need to filter data based on a column. The column has around 5 values and i need to filter out 2 values in one sheet and the rest 3 to remain in the same sheet.
Now instead of using cell by cell comparison to check whether the value of the cell falls in any of the above 2 values and then cut paste the row into another sheet. This wouldn't work with 200k+ records and simply hangs,.
Instead am planning to take the auto filter method. I tried using the 'Record macro' feature, but the problem is that it gives me some error like
"Excel cannot create or use the data range reference because its too complex.Try one of the following
Use data that can be selected in rectangle
Use data from the same sheet"
Moreover how to copy paste only the filtered values to another sheet? If I try to copy paste directly or special paste as 'values' then also even the hidden rows get copy pasted.
Below is the macro code i have been tampering around with
Sub Macro34()
'
' Macro34 Macro
'
'
Rows("1:1").Select
Selection.AutoFilter
ActiveSheet.Range("$A$1:$T$81335").AutoFilter Field:=6, Criteria1:="=242", _
Operator:=xlOr, Criteria2:="=244"
Cells.Select
Selection.Copy
ActiveWindow.SmallScroll Down:=21
Sheets("Sheet2").Select
ActiveWindow.SmallScroll Down:=-18
Range("A1").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Selection.ClearContents
Range("A1").Select
Sheets("Sheet1").Select
Selection.Copy
Sheets("Sheet2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Sheet2").Select
ActiveWindow.SmallScroll Down:=93
Sheets("Sheet1").Select
ActiveWindow.SmallScroll Down:=-9
ActiveWindow.ScrollRow = 1
Rows("1:1").Select
Application.CutCopyMode = False
Selection.AutoFilter
End Sub
There might be some junk lines of code above as its generated using the 'record macro' feature.
Could someone please help me. The problem is the amount of data present in excel. Cant excel not handle this much data in VBA? Am using Excel 2007
Here's your code cleaned up:
Sub Macro34()
' Turn off autofiltering
If ActiveSheet.AutoFilterMode Then ActiveSheet.AutoFilterMode = False
' Turn it back on
Rows(1).AutoFilter
' Set the autofiltering conditions
Rows(1).AutoFilter Field:=6, _
Criteria1:="=242", _
Operator:=xlOr, _
Criteria2:="=244"
' Copy only the relevant range
Range("A1", _
Cells(65536, Cells(1, 256).End(xlToLeft).Column).End(xlUp)).SpecialCells(xlCellTypeVisible).Copy
' Paste the data into Sheet2 (assuming that it exists)
Sheets("Sheet2").Range("A1").PasteSpecial xlPasteValuesAndNumberFormats
Application.CutCopyMode = False
End Sub
The key is that SpecialCells part.
Now, as much as I love a good autofilter copy/paste, when you're dealing with that much data, you might want to look into using ADO, which would allow you to query your Excel worksheet using SQL.
A good overview of ADO in VBA is provided here: http://www.xtremevbtalk.com/showthread.php?t=217783.
In the 1st empty column to the right of your data insert a formula that tests for your criteria: e.g.
=if(or(a2=242,a2-244),"Move","Keep")
then in your macro, sort the whole 200,000 line data set by that column before you attempt the filter and cut visible code described in answer1.
This will make the block of data to be cut-n-pasted one contiguous range. This should get around the 'data range too complex' error.

Resources