I have an excel document that is, and looks physically like a report. I only need some of the data. What is the best of coming up with a formula that gets me this information. Document has 88 entries.
You can click the image for a full-size version:
I want to come up with a search that returns the stuff in yellow. Any idea how to get that done? Or is this a manual search type of deal? I'm asking, not because I want to save 3 hours on doing this, but because I would like to save time in the future. Thanks!
As long as your template is in the same format, the below code should work. I tried to keep it as simple as possible so you can see what the individual steps do. You an adjust the columns where the data is pasted to suit. You will need to first create a sheet called 'Extract' and change any occurrence of 'YourSheetNameHere' within the code.
Sub Extract()
Dim Page, Company, Num, Name, ProjMan, TotalVal, Fee As String
Dim r, c As Integer
c = 1
Sheets("YourSheetNameHere").Select
For r = 1 To 4680
If Left(Range("J" & r).Value, 4) = "Page" Then
'Stores the values
Page = Range("J" & r)
ProjMan = Range("J" & r + 2)
TotalVal = Range("J" & r + 4)
Company = Range("J" & r + 4)
Num = Range("J" & r + 6)
Name = Range("J" & r + 7)
Fee = Range("H" & r + 31)
'Pastes the values in a new sheet called Extract (which you will need to create first)
Sheets("Extract").Select
Range("A" & c) = Page
Range("B" & c) = ProjMan
Range("C" & c) = TotalVal
Range("D" & c) = Company
Range("E" & c) = Num
Range("F" & c) = Name
Range("G" & c) = Fee
c = c + 1
Sheets("YourSheetNameHere").Select 'You will need to adjust to suit
End If
Next r
End Sub
Related
I have columns in my csv like this:
Id Name Price
1 Level X discontinued 34
3 Level Y Dicontinued 64
7 Level Z 94
I want to check if in column Name are discontinued or Dicontinued
If yes delete row, if not, dont do nothing, so my final result will be:
Id Name Price
7 Level Z 94
A solution can be running the following Excel Macro ExampleMacro with the following setup. This code will filter the first worksheet [here TotalList] copying the content in a second worksheet [here Filtered]
NOTE: please use the same names I used or change the code of the following macro accordingly if you prefer to change the names. Otherwise it will not work
Sub ExampleMacro()
Dim i As Integer
Dim j As Integer
Set ShMaster = ThisWorkbook.Sheets("TotalList")
Set ShSlave = ThisWorkbook.Sheets("Filtered")
'cleanup for next macro executions
ShSlave.UsedRange.Clear
'copying the headers
ShSlave.Range("A1").Value = ShMaster.Range("A1").Value
ShSlave.Range("B1").Value = ShMaster.Range("B1").Value
ShSlave.Range("C1").Value = ShMaster.Range("C1").Value
'searching what to keep
j = 2
For i = 2 To ShMaster.UsedRange.Rows.Count
'MsgBox "value is " & InStr(1, (Range("B" & i).Value), "discontinued")
If InStr(1, (ShMaster.Range("B" & i).Value), "discontinued") = 0 Then
While ShSlave.Range("C" & j).Value <> ""
j = j + 1
Wend
ShSlave.Range("A" & j).Value = ShMaster.Range("A" & i).Value
ShSlave.Range("B" & j).Value = ShMaster.Range("B" & i).Value
ShSlave.Range("C" & j).Value = ShMaster.Range("C" & i).Value
End If
Next i
End Sub
I'm trying to find a solution for the following problem:
I have a sheet containing information on several customers with several projects each. The combiniation of customer + projectname is unique.
On a different sheet I want to be able to:
select the customer from a dynamic dropdown-list without duplicates (I have managed that)
then be presented with a second dropdown, reduced to only those projects of the selected customer
have the information in cells (C5:C7) filled automatically
As the data-sheets content is dynmaic and will contain lots of data, named tables are no option.
I'd be grateful I anyone had an idea on how to solve the problem!
It can be achieved through VBA. I have written the below code and worked for me.
Input sheet:
Try the below code.
Sub CustomerAndProject()
Dim Customer As String, Project As String, Info1 As String, Info2 As String, Info3 As String
Dim TotalCustomers As Integer, m As Integer
m = 1
'Get Total customers
TotalCustomers = Worksheets("Sheet1").Range("A1").End(xlDown).Row
'First loop to pick customers
For i = 2 To TotalCustomers
Customer = Worksheets("Sheet1").Range("A" & i).Value
'Second loop to pick the projects related to customer
For k = 2 To TotalCustomers
Project = Worksheets("Sheet1").Range("B" & k).Value
'Function r=to validate the duplicate customers and projects
If CustomerValidationForDuplication(Project, Customer, TotalCustomers) = False Then
'Third loop to pick and paste info data related to customer and project
For j = 2 To TotalCustomers
If Worksheets("Sheet1").Range("A" & j).Value = Customer And Worksheets("Sheet1").Range("B" & j).Value = Project Then
Worksheets("Sheet2").Cells(1, m).Value = Customer
Worksheets("Sheet2").Cells(2, m).Value = Project
If IsEmpty(Worksheets("Sheet1").Range("C" & j).Value) Then
Else: Info1 = Worksheets("Sheet1").Range("C" & j).Value
Worksheets("Sheet2").Cells(3, m).Value = Info1
End If
If IsEmpty(Worksheets("Sheet1").Range("D" & j).Value) Then
Else: Info2 = Worksheets("Sheet1").Range("D" & j).Value
Worksheets("Sheet2").Cells(4, m).Value = Info2
End If
If IsEmpty(Worksheets("Sheet1").Range("E" & j).Value) Then
Else: Info3 = Worksheets("Sheet1").Range("E" & j).Value
Worksheets("Sheet2").Cells(5, m).Value = Info3
End If
End If
Next
m = m + 1
End If
Next
Next
End Sub
Function CustomerValidationForDuplication(ProjectToBeVerified As String, CustomerToBeVerified As String, TotalCustomers As Integer) As Boolean
For l = 1 To TotalCustomers
If ProjectToBeVerified = Worksheets("Sheet2").Cells(2, l) Then
For m = 1 To TotalCustomers
If CustomerToBeVerified = Worksheets("Sheet2").Cells(1, m) Then
CustomerValidationForDuplication = True
Exit For
Else
CustomerValidationForDuplication = False
End If
Next
Else
CustomerValidationForDuplication = False
End If
If CustomerValidationForDuplication = True Then Exit For
Next
End Function
Output sheet:
Let me know if it works for you.
Note: I am new to VBA so my code won't be friendly. Edits are welcome.
I am making a GUI in excel that allows the user to enter information into the spreadsheet just by using the GUI. I have run into a problem however. I can't seem to get the date to format right. this is the code I have for it (it being the code for the GUI:
Dim AN As Worksheet
Set AN = ThisWorkbook.Sheets("Sheet2")
Dim n As Long
n = AN.Range("A" & Application.Rows.Count).End(xlUp).Row
'AN.Range("A" & n + 1).Value ='
AN.Range("B" & n + 1).Value = Me.yyyy.Value + "-" + Me.mm.Value + "-" + Me.dd.Value
'AN.Range("C" & n + 1).Value ='
AN.Range("D" & n + 1).Value = Me.N_O_B.Value
AN.Range("E" & n + 1).Value = Me.Address_street.Value
AN.Range("F" & n + 1).Value = Me.City_info.Value
AN.Range("G" & n + 1).Value = Me.State_info.Value
AN.Range("H" & n + 1).Value = Me.Zip_info.Value
AN.Range("I" & n + 1).Value = Me.Lname.Value
AN.Range("J" & n + 1).Value = Me.Fname.Value
AN.Range("K" & n + 1).Value = Me.Minitial.Value
AN.Range("L" & n + 1).Value = Me.Suffix.Value
AN.Range("P" & n + 1).Value = Me.Busi_zip.Value
AN.Range("X" & n + 1).Value = Me.Shrt_Descript.Value
I am trying to get the date to show up in column B. It is showing up in column B, but not the way I thought it would. So in the GUI you enter the year, the month, and the date. Then I tried to make the code take the information and put it in a YYYY/MM/DD format but its not working. I have to have it in this format. Any advice would be helpful.
Force the date's raw value and then format the cell.
AN.Range("B" & n + 1).Value = dateserial(Me.yyyy.Value, Me.mm.Value, Me.dd.Value)
AN.Range("B" & n + 1).numberformat = "yyyy-mm-dd"
btw, the correct string concatenation operator is an ampersand (e.g. &). While a plus sign may work, it is best avoided, particularly when working with numbers.
I have simple problem, but I am not able to find a "fix" for it.
I have the following code:
cmdSQLData.CommandText = Query 'some select
cmdSQLData.CommandType = adCmdText
cmdSQLData.CommandTimeout = 0
Set rs = cmdSQLData.Execute()
j = 1
x = 6 'the line I want the data to start
rs.MoveFirst
Do Until rs.EOF
Sheet1.Range("A" & x).Value = rs![name1]
Sheet1.Range("B" & x).Value = rs![name2]
Sheet1.Range("C" & x).Value = rs![name3]
Sheet1.Range("D" & x).Value = rs![name4]
.
.'lot more columns
.
Sheet1.Range("AC" & x).Value = rs![name28]
If x = 10 Then 'after each 10 lines to create another sheet
x = 6
j = j + 1
Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name ="Sheet" & j
End If
Loop
cn.Close
Set cn = Nothing
Set rs = Nothing
Set cmdSQLData = Nothing
I need that when there are more "lines" in the record set than lets say 10, to have another sheet created, Sheet2, where to have the next 10 lines inserted and if the record set still has values to have another sheet created, Sheet3 and so on, until the record set has been fully parsed.
The problem is that for getting the data from record set to excel, i use Sheet1, hardcoded. I tryed to use instead of Sheet1, Sheet[j] or Sheet(j) and to increment "j" each time I create a new sheet, but I get an error, therefore I cannot use Sheet[j].Range("A" & x).Value=rs![name1] or Sheet(j).Range("A" & x).Value=rs![name1].
Any hints?
While I personally believe that collecting all data into one sheet before dividing them into set of x rows is much better, there's another way of going about it using your code. Instead of using Sheet1, use Sheets(j) where j is the sheet index. Also, you can do Sheets("Sheet" & j) as well.
Using the second approach, replace the respective block of your code with the following:
Set rs = cmdSQLData.Execute()
j = 1
x = 6 'the line I want the data to start
rs.MoveFirst
Do Until rs.EOF
With Sheets("Sheet" & j)
.Range("A" & x).Value = rs![name1]
.Range("B" & x).Value = rs![name2]
.Range("C" & x).Value = rs![name3]
.Range("D" & x).Value = rs![name4]
.
.'lot more columns
.
.Range("AC" & x).Value = rs![name28]
End With
x = x + 1
If x = 16 Then 'after each 10 lines to create another sheet
x = 6
j = j + 1
Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = "Sheet" & j
End If
Loop
You also forgot to increment your x so it will keep on overwriting row 6 again and again. Here, you should be targeting x=10 but x=16 since you start from row 6 based on the initial value of x. The ten rows including row 6 ends in row 15. Once x is equal to 16, it should trigger your IF block.
I have corrected that for you in the above code. Let us know if this helps.
Try this for adding new sheet:
Do Until rs.EOF
If x = 10 Then
Set ws = Thisworkbook.Sheets.Add(After:=Thisworkbook.Sheets(Thisworksheet.Sheets.Count)
ws.Name = "Sheet" & j
x = 6
j = j + 1 ' although you don't really need this, sheet number increment automatically.
End If
ws.Range("A" & x).Value = rs![name1]
.
.
x = x + 1
Loop
i just assumed you only have problem on adding sheet.
Hope this helps.
In my worksheet some cells values are based on other cells
Info worksheet
A1: 5
B1: =A1
Design worksheet
A1:
Is there a way to copy and read the value in B1? I'm trying to use the value in a for loop, with no luck.
Sheets("Info").Select
For i = 1 to 5
If Range("B" & i).Value <> 0 Then
Range("B" & i).Copy Destination:=Sheets("Design").Range("A" & x)
'Sheets("Design").Range("A" & x).Value = Sheets("Offerte").Range("B" & i).Value
x = x + 1
End If
Next i
Your example doesn't seem to match the code well. The line
If Range("B" & i).Value = 1 Then
means that nothing will be copied in your example. It's looking for a cell with 1 in it. Why do you need that If statement at all?
EDIT I am guessing you're just checking that there's something in the cell to copy? I would probably do it this way:
If Trim(Range("B" & i).Value) <> "" Then
Also - did you miss out setting x=1?
There is more than one way to do it. One of them is using 'offset', which is a function that really worth understand. It basically points to a amount of rows / columns from the original cell.
Sub test()
Dim oCell As Excel.Range
Dim i As Integer
Dim x As Integer
Set oCell = Sheets("Info").Range("B1")
x = 1
For i = 1 To 5
If oCell.Offset(i, 0).Value = 1 Then
oCell.Offset(i, 0).Copy Destination:=Sheets("Design").Range("A" & x)
x = x + 1
End If
Next i
End Sub
Besides, you can assert the value instead of using the copy property. Notice it won't work unless x is an integer > 0.
Sub test2()
Sheets(3).Select
x = 1
For i = 1 To 5
If Range("B" & i).Value = 1 Then
Sheets(4).Range("A" & x).Value = Range("B" & i).Value
'Sheets("Design").Range("A" & x).Value = Sheets("Offerte").Range("B" & i).Value
x = x + 1
End If
Next i
End Sub