I have a spredsheet on Excel and I must get the number of items from a row, somethink like this:
Item1 | Qty1 | Item2 | Qty2 | Item3 | Qty3 | ... | ItemZ | QtyZ |
Into a second sheet, I must populate with these data, but with just two Columns (Items and Qty).
There is any way to do that? I'd rather a solution that uses DGET or VLOOKUP (it seems faster), althought any feasable way to that would make me very happy :D
I've tried use a loop function, using Find + move to the left + copy and paste the qty. The problem was that this tooked like forever (plus my Excel crashed a few times).
So folks, could you help me?
If I understood correctly what you're after, then here's something basic to get you started (it's in VBA, not using Excel functions, but you'll hopefully get the idea):
Public Sub CopyDown()
Dim i As Long
Dim j As Long
j = 1
For i = 1 To Sheet1.Cells(1, Sheet1.Columns.Count).End(xlToLeft).Column Step 2
Sheet2.Cells(j, 1) = Sheet1.Cells(1, i)
Sheet2.Cells(j, 2) = Sheet1.Cells(1, i + 1)
j = j + 1
Next i
End Sub
It's not terribly robust as there's no error checking, but it should work for the case you've described. It assumes Items are arranged across row 1 in odd columns (1, 3, etc.) and Quantities are in even columns (2, 4, etc.) in "Sheet1". Then they are copied to ascending rows (from 1 onwards) in Columns A (for Items) and B (for Quantities) in "Sheet2". Let me know if you need more explanation.
Related
I have looked at a bunch of questions like this, but I have only found formulas, and VB examples that don't appear to check the values of cells in a column.
I was able to derive the following formula in Excel:
=IF(AND(ISNUMBER(SEARCH("Cat",R2)),OR(ISNUMBER(SEARCH("5E",R2)),ISNUMBER(SEARCH("6",R2))), ISNUMBER(SEARCH("Patch",R2)), ISNUMBER(SEARCH("Cables",R2))), "CAT 5E Ethernet Cables")
The problem is that this formula only checks for 1 out of 500 possible values. This is not productive. Plus, I have to make it one big formula when I check the entire row, because if I don't, the formula overwrites the result of the previous formula...
So, Visual Basic... I think I may have better luck scripting some kind of IF ELSE or CASE statement. I just do not understand how to do this in excel. I need to achieve the same thing as the formula above, but instead of checking for one set of conditions,
I need to check for multiple, and populate the S & T columns based on the result of each set of conditions.
I found this webpage that just mentions Excel and shows a VB IF - ELSE statement. How can I make this statement check Excel columns?
I tried the selected answer in this post with no luck:
Private Sub UpdateCategories()
Dim x As Long
For x = 1 To 5000
If InStr(1, Sheet1.Range("$B$" & x), "cat") > 0 And InStr(1, Sheet1.Range("$B$" & x), "5e") > 0 Then
Sheet1.Range("$T$" & x) = Sheet1.Range("$T$" & x) & "CAT 5E Ethernet Cables (Test)"
End If
Next
End Sub
Any help is appreciated. Thanks in advance!
Assuming you choose the route of using a data table sheet to compare to your string.
You would need to have a sheet looking like this (Maybe this is not what you want because I didn't thoroughly understand how your data looks like but the idea remains). You could have sub-category if you want, as well as category, in a third column.
column A | column B
keyword |category
CAT |ATX Cases
5e |Mini-ITX Cases
important words |MicroATX Cases
...
This would need to be filled manually. I'm not sure about the amount of data you're looking at. It can be pretty rapid if you can copy/paste stuff efficiently, depending on the form of your data.
When you have that, loop using this code. I assume the data table is in Sheet1, columns A and B and the values are in Sheet2, column A.
dim listLength as integer 'number of values to look at
dim i as integer
dim dataLength as integer 'number of keywords
dim j as integer
dim keyword as string
dim value as string
listlength = Sheet2.Cells(Rows.Count, "A").End(xlUp).Row - 1 'assuming you start on row 2
datalength = Sheet1.Cells(Rows.Count, "A").End(xlUp).Row - 1 'assuming you start on row 2
for i = 2 to listLength + 1
value = Sheet2.Range("A")(i)
for j = 2 to dataLength + 1
keyword = Sheet1.Range("A")(j)
if instr(value, keyword) <> 0 then
' what happens when the keyword is present goes here
end if
next j
next i
I am working on a small VB.Net app that will generate an Excel workbook based on several queries from a database. I have a query that returns a datatable containing a date (Outage_Date), ID (ID) and an issue type (Issue_Type). I am trying to place these in staggered columns based on the ID and the issue type, but I'm struggling to come up with the logic to do this.
The datatable looks like this:
Outage_Date ID Issue_Type
1/1/2010 123 Start
2/5/2010 456 Start
3/17/2011 123 Minor
1/2/2012 123 Major
9/25/2012 456 Major
10/5/2012 456 Minor
The output should look like this:
Date 123 456
1/1/2010 Start
2/5/2010 Start
3/17/2011 Minor
1/2/2012 Major
9/25/2012 Major
10/5/2012 Minor
How can I approach this programmatically? Any help is appreciated. I'll gladly accept psuedocode or vb.net. :)
This method uses LINQ to DataSet to query the DataTable, assumes Option Infer On, and is a mix of code and pseudocode! I don't know what you are using to build the Excel spreadsheet, so I made that part up based on ClosedXML syntax. It's also untested, so let me know how it works out - hopefully it's enough to point you in the right direction, although there may be more elegant solutions!
' Build a list of the IDs
Dim ids = datatable.AsEnumberable() _
.Select(Function(dr) dr.Field(Of Integer)("ID")) _
.Distinct() _
.OrderBy(Function(x) x) _
.ToList()
' Headings
Dim row = 1, col = 1
worksheet.Cell(row, col).Value = "Date"
For Each id In ids
col += 1
worksheet.Cell(row, col).Value = CStr(id)
Next
' Data Values
For Each dr In datatable.Rows
row += 1
col = 1
worksheet.Cell(row, col).Value = dr.Field(Of Date)("Outage_Date")
col += 1
' Work out how many columns to shift the issue type over
Dim offset = ids.IndexOf(dr.Field(Of Integer)("ID"))
col += offset
worksheet.Cell(row, col).Value = dr.Field(Of String)("Issue_Type")
Next
I am facing an issue when trying to compile a multiple criteria Index/Match code in VBA. This might be simple - but i am fairly new to VBA and nothing i have found around here worked.
Example:
I have a large amount of data in a specified range: Sheets("CustomerAccounts").Range(CustomerSheetRange)) - I need VBA to return data from column titled "Values" by checking three criteria: Customer = X, Type = External, OriginCountry = UAE (columns are not adjacent in the original spreadsheet)
The criteria are stored in separate variables set by user of the macro beforehand.
Customer | Type | Origin | Destination | Values
X | Internal | UAE | SA | Value 1
Y | Internal | UAE | SA | Value 2
X | External | UAE | SA | Value 3
X | External | ZA | UAE | Value 4
At the moment i have the following (quite bulky) code which finds the value using one criteria - OriginCountry variable.
The code searches for it in a pre-specified column - OriginCountryColumn.
ResultString = Application.Index(Sheets("CustomerAccounts").Range(CustomerSheetRange), Application.Match(OriginCountry, Sheets("CustomerAccounts").Range(OriginCountryColumn), 0), Application.Match("Values", Sheets("CustomerAccounts").Range(TitleRowCust), 0))
I would like to modify the code to also match the Type and The customer.
Is it possible to expand the above Index/Matxh function - or should i use a different approach?
Any advice is appreciated.
You may walk through rows checking matches:
Dim row as Long
With Sheets("CustomerAccounts").Range(CustomerSheetRange))
For row = 2 To .Rows.Count 'Starts in 2 to ignore header!
If .Cells(row, costumerCol).Value Like costumerCriteria And .Cells(row, typeCol).Value Like typeCriteria And .Cells(row, originCol).Value Like originCriteria Then
'This is a match!
Debug.Print .Cells(row, valueCol)
End if
Next
End With
You must replace costumerCol, typeCol, originCol and valueCol with corresponding column number and costumerCriteria, typeCriteria and originCriteria with criteria specified.
If column indexes are also variable, make a search for them in first row before walking through rows.
First, format the range containing your data to a Table (See http://office.microsoft.com/en-001/excel-help/quick-start-create-an-excel-table-HA010359200.aspx on how to do that). Once done, use the following VBA code:
SomeCustomer = Range("...").Value
SomeType = Range("...").Value
SomeOrigin = Range("...").Value
ActiveSheet.ListObjects("Table1").Range.AutoFilter Field:=1, Criteria=SomeCustomer
ActiveSheet.ListObjects("Table1").Range.AutoFilter Field:=2, Criteria=SomeType
ActiveSheet.ListObjects("Table1").Range.AutoFilter Field:=3, Criteria=SomeOrigin
Notes:
You might have to customize this macro for your specific needs
Name of table can be found/modified through Formulas>Name Manager
ActiveSheet might be modified to the actual sheet you are using
I gotta serious problem here.. any kind of help is much appreciated!!
I have two huge text files (130 MB)each with thousands of records in each. I need to compare the two files using vba or by any means and generate a spreadsheet which includes the header and with two additional columns. The two additional columns will be the file name and in the next column it should display in which particular column is error. Each record will be having multiple discrepancies. One file can have the records which cannot be found in the other file. So this condition should also be recorded in the spreadsheet.
Example:
Media Events: Taking one record from each.
00000018063|112295|000|**0009**|
PROL:
00000018063|112295|000|**0013**|
In the above example, the records are from two files. The highlighted ones are the differences between the records. So the output should be like this..
HH_NUMBER | CLASS_DATE | MV_MIN DURATION File Mismatc Mismatch Reason
00000018063 | 112295 | 000 **0009** Media Events Mismatches in DURATION
00000018063 | 112295 | 000 **0013** PROL Mismatches in DURATION
00000011861 | 112295 | 002 0126 Media Events missing in PROL file
It seems there are three problems here:
1) Find matching records (first column) between two files.
2) Compare records that match on the first column - if there is a difference, record what the difference is
3) If a record exists in one file but not the other, record that.
I am going to assume that the two "huge files" are in fact separate sheets in the same excel workbook, and that the records are sorted on the first key. This will speed up processing significantly. But speed is a secondary concern, I assume. I also assume there is a third sheet where you put the output.
Here is an outline of VBA code - you will have to do a bit of work to get it "just right" for your application, but I hope this gets you going.
Sub compare()
Dim s1 as Worksheet
Dim s2 as Worksheet
Dim col1 as Range
Dim col2 as Range
Dim c as Range
Dim record1 As Range, record2 As Range, output As Range
Dim m
Dim numCols as Integer
numCols = 5 ' however many columns you want to compare over
Set s1 = Sheets("Media")
Set s2 = Sheets("Pro")
Set output = Sheets("output").Range("A2")
Application.ScreenUpdating = False
s1.Select
Set col1 = Range("A2", [A2].End(xlDown));
s2.Select
Set col2 = Range("A2", [A2].End(xlDown));
On Error Resume Next
For Each c in col1.Cells
m = Application.Match(c.Value, col2, 0);
If isError(m) Then
' you found a record in 1 but not 2
' record this in your output sheet
output.Value = "Record " & c.Value & " does not exist in Pro"
Set output = output.Offset(1,0) ' next time you write output it will be in the next line
' you will have to do the same thing in the other direction - test all values
' in 2 against 1 to see if any records exist in 2 that don't exist in 1
Else
' you found matching records
Set record1 = Range(c, c.offset(0, numCols))
Set record2 = Range(col2.Cells(m,1), col2.Cells(m,numCols))
' now you call another function to compare these records and record the result
' using the same trick as above to "go to the next line" - using output.Offset(1,0)
End If
Next c
End Sub
You could do this with formulas:
See
MS KB: Use Excel to compare two lists of data
Me Excel.com - Creating a list of non-matching values
ExcelExperts.com - Extracting non-matching entries from two columns in a third column
To give you an idea, basically, if you have two lists in columns A & B, you could use formulas like below in columns C and D to show the matching or non-matching:
In C1,
=If(isna(match(A1,B:B,0)),A1,"")
and, in D1
=IF(Isna(Match(B1,A:A,0)),B1,"")
both copied down.
FURTHER READING:
Excel Index Function and Match Function - Contextures MVP
Excel VLOOKUP and Index & Match - Excel User MVP
Excel User MVP - Excel’s Best Lookup Method: INDEX-MATCH
I’m struggling trying to develop an automated solution for the following challenge (ie apart from a button press, no user intervention):
I have a master ‘sheet that contains Accrual figures in monthly columns and an associated Receipt Number for this in a column immediately to the right. The Receipt columns have the month in the form: ‘Feb’, ‘Jun’, ‘Dec’ at the top.
I need to return a variety of cell data to another summary ‘sheet in the workbook from each row that matches the following criteria:
Identify the Receipt column based on a match of the month with an entered month in cell ‘x’ in the summary ‘sheet, eg if I type ‘Mar’, find the column headed ‘Mar’ in the master ’sheet.
Ignoring blank rows (ie there are data in Column A), if the cell in the first row of the Receipt column is blank, identify the row, select 6 different cells and return the contents to 6 specific cells in the first blank row (from a given row number) in the summary ‘sheet – then move onto the next row in the column and continue this process until the end (or a row limit). NB: the 'blank' cell will have a fill colour (conditionally formatted).
If the cell contains data, move to the next row down and continue the process.
A VBA routine I can attach to an onscreen button to update the results each time would do the job nicely. Although I've picked up bits of really useful code here, eg for checking each row for given conditions, I can’t get my head around a working solution to include returning the relevant cells to the summary 'sheet...
Any and all feedback greatly appreciated.
(Sorry - can't post images / screenshots yet...)
Update
Thanks for the quick response, and apols I couldn't append/paste-in a sample of the spreadsheet - apparently I need 10 points... :)
Slightly Different summary sheet (Sheet1). The columns are: Month (Col A), then 4 cells (TBD) to be returned to cols B-E, then Receipt No (Col F). The data come from each identified row in the master sheet (Sheet4) and are placed in the next available blank row in Sheet1. I can mod any examples given to match the actual positions.
I have the criteria for selecting the row (this is from a loop I've got working to identify the row, but using a fixed column reference [26 - Col Z] for a specific month):
If Not Cells(TheRow, 3).Value = "" And Cells(TheRow, 26).Value = "" And Cells(TheRow, 6).Value < Cells(TheRow, 25).Value Then... (do the other bit I'm stuck on)
Hope this is a bit clearer. Appreciate your help.
Can't add a comment, or chat (!) so further update:
Thanks Tony
The month column in the summary is to confirm the month reported on, as this will change when the user overwrites the source cell for the month they wish to parse the master sheet with. The person this data goes to will get these 7 columns and nothing else.
The mechanism has to find the Receipt col (month), then identify that row entry is blank AND col 3 on that row is not blank AND that the Accrual value [Rng.Column - 1] is greater than the PO value (Col 4) on that row. Once these criteria are established, the Receipt, Accrual, PO and 3 other data are selected, copied and pasted into the summary sheet on the next available blank row.
The master sheet has Accrual and Receipt for each month, so there is only one column to identify.
Hope this helps...
I am struggling to visualise you worksheets. I see the master sheet as something like:
... |Accrual| Jan|Accrual| Feb|Accrual| Mar|Accrual| Apr| ...
... | 1.23|A12 | | | 23.67|A14 | | |
... | | | 56.78|C34 | 178.12|C56 | | |
... | 2.34|B678 | | | | | 123.82|B821 |
... | | | | | 96.52|D56 | | |
Somewhere within the Summary sheet there is a list of months of interest.
I need a variable:
Dim MonOfInt As String
and a loop within which a month of interest will be loaded from the worksheet into this variable:
With Sheets("Summary")
MonOfInt = .Cells(R, C).Value
End With
The following is a possible skeleton for the code to move values for the month of interest:
Dim ColCrnt As Long
Dim Rng As Range
Dim RowCrnt As Long
Dim RowLast As Long
:
With Sheets("Master")
' Look for month of interest in row 1
Set Rng = .Rows(1).Find(MonOfInt)
End With
If Rng Is Nothing Then
' No columns for this month in Master
Else
' Accrual and Receipt columns for this month found
ColCrnt = Rng.Column - 1 ' Accrual column for month
' Find last used row in Accrual column
RowLast = .Cells(Rows.Count, ColCrnt).End(xlUp).Row
For RowCrnt = 2 To RowLast
' Code to extract values from Master and move to Summary here
Next
End If
End With
If you can add information to your question to confirm my visualisation and to give more information about (1) how to detect is a row is blank (other than testing the whole row which is an option) and (2) the source and destination of the six cells then I will try to pad out this answer.