Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
schmagekie
Dec 2, 2003
I'm trying to get a list of unique values from a selection of multiple columns/ranges on a new sheet using a macro. I have it kind of working, but I'm relatively new VBA and hitting my limit.
If anyone could take a look, I'd really appreciate it.

What's broken:
Needs error handling if a pivot table/chart, etc. is selected.
If multiple selections are in the same column, they're going to different output columns, while I'd like them to be in the same output column.
The output destination should be a range with reasonable dimensions, not the entire column.
I have the output columns increment by one, but I'd like to use the next blank column.
Only the values should be copied, not the formatting.
I can't get sort ascending to work.
code:
Sub Get_Uniques()
''''''''''''''''''''''''
'Variables             '
''''''''''''''''''''''''
Dim rRng As Range           'selection
Dim nRng As Range           'column of selection if more than one
Dim jAreas As Long          'area of selection if non-continuous
Dim sShtNameOrig As String  'source sheet name
Dim sShtName As String      'new sheet name
Dim ws As Worksheet         'new worksheet
Dim bShtCheck As Boolean    'check if new sheet name exists
Dim rDest As Range          'destination for uniques/sorting
Dim i As Long               'increment destination column
Dim j As Long               'count for columns in area

''''''''''''''''''''''''
'Declarations          '
''''''''''''''''''''''''

Set rRng = Selection
sShtName = ActiveSheet.Name
sShtNameOrig = ActiveSheet.Name
i = 1

''''''''''''''''''''''''
'Action                '
''''''''''''''''''''''''

'todo: exit if pivot table/chart, etc is selected

'set new sheet name
If Len(sShtName) <= 24 Then
    sShtName = sShtName & " Unique"
Else:
    sShtName = Left(sShtName, 24) & " Unique"
End If

'check if new sheet name exists, if yes set ws
For Each jWS In Worksheets
    If sShtName = jWS.Name Then
        Set ws = Sheets(sShtName)
        bShtCheck = True
        Exit For
    End If
Next jWS

'if sheet name doesn't exist, add it
If bShtCheck = False Then
    Set ws = Sheets.Add(After:=Sheets(sShtNameOrig), Type:="Worksheet")
    ws.Name = sShtName
End If

'down to business
For jAreas = 1 To rRng.Areas.Count                      'for each area in selection if non-continuous (todo: make multiple selection in the same source column end in the same destination column)
    For j = 1 To rRng.Areas(jAreas).Columns.Count       'for each column in area
        Set nRng = rRng.Areas(jAreas).Columns(j)
    
        Set rDest = ws.Columns(i)                       'todo: make this the next empty column, set an actual range, not entire column
        
        'paste from selection
        nRng.SpecialCells(xlCellTypeConstants).Copy Destination:=rDest      'todo: paste values only, not formats
        
        'remove duplicates
        rDest.RemoveDuplicates Columns:=1, Header:=xlGuess 'xlyes xlno
        
        'sort ascending with headers (not working)
        rDest.SortSpecial xlPinYin, , xlAscending, , , , , , xlYes, , , xlSortColumns
        
        i = i + 1                                       'increment column
    Next j
Next jAreas
    
End Sub

Adbot
ADBOT LOVES YOU

schmagekie
Dec 2, 2003
Thanks for checking this out, Old James. Color added for emphasis.
Edit: and if I were to run it again on column C, on the output sheet, F and M should be in column D.



Here's my favorite macro to create a pivot table (with a custom pivot table style) from a selection, or if no selection is made, it uses the current region, and sets the layout to classic.

code:
Sub CreatePivotTable()
'activated by Ctrl + t as defined in Workbook_Open()

Dim rData As Range
Dim pcNew As PivotCache
Dim rCell As Range
Dim iFieldCnt As Long
Dim ptNew As PivotTable
Dim sShName As String
Dim sShNameOrig As String
Dim pf As PivotField
Dim i As Long
Dim ws As Worksheet

Const sField = "Field"
iFieldCnt = 1

ActiveSheet.UsedRange

'make sure a range is selected
If TypeName(Selection) = "Range" Then
    'if a single row is selected, set range to Current Region
    If Selection.Rows.Count = 1 Then
        Set rData = ActiveCell.CurrentRegion
    Else
        Set rData = Intersect(Selection, ActiveSheet.UsedRange)
    End If
    
    'put column headers in blank cells
    For Each rCell In rData.Rows(1).Cells
        If IsEmpty(rCell.Value) Then
            rCell.Value = sField & iFieldCnt
            iFieldCnt = iFieldCnt + 1
        End If
    Next rCell
    
    'set new sheet name to source name & Pivot
    sShNameOrig = ActiveSheet.Name
    sShName = ActiveSheet.Name
    
    If Len(sShName) > 25 Then
        sShName = Left(sShName, 25) & " Pivot"
    Else: sShName = sShName & " Pivot"
    End If

    'add new sheet to the right of source
    Set ws = Sheets.Add(After:=Sheets(sShNameOrig), Type:="Worksheet")
    ws.Name = sShName
    
    'create and set default Pivot Table Style to custom style
    'Call PivotTableStyle
    
    Set pcNew = ActiveWorkbook.PivotCaches.Create(xlDatabase, rData)
    Set ptNew = pcNew.CreatePivotTable(ws.Range("A3"))
    
    'set layout to Classic
    With ptNew
        .InGridDropZones = True
        .RowAxisLayout xlTabularRow
        .ColumnGrand = True
        .RowGrand = False
        '.RepeatAllLabels xlRepeatLabels
        .ShowTableStyleRowHeaders = False
        .ShowDrillIndicators = False
        .HasAutoFormat = True
        .SaveData = True
        .ManualUpdate = True
    End With
    
    ws.Range("A3").Select
    
End If

End Sub

Only registered members can see post attachments!

schmagekie fucked around with this message at 09:21 on Jun 15, 2014

schmagekie
Dec 2, 2003
Here are a couple subs to shift everything you select to the left, and delete the entire row if column B = 0.
code:
Sub AlignLeft()
    Dim oRng As Range
    Dim jCol As Long
      
On Error GoTo ErrorHandler

    Set oRng = Intersect(Selection, ActiveSheet.UsedRange)

    With Application
        .ScreenUpdating = False
        .Calculation = xlCalculationManual
    End With
    
    On Error Resume Next
    
    For jCol = 1 To oRng.Columns.Count
        oRng.Columns(1).SpecialCells(xlCellTypeBlanks).Delete Shift:=xlToLeft
    Next jCol
    
    On Error GoTo 0
        
ErrorExit:
    With Application
        .ScreenUpdating = True
        .Calculation = xlCalculationAutomatic
    End With
    
Exit Sub
    
ErrorHandler:
    MsgBox Err.Description, vbCritical
Resume ErrorExit

End Sub
code:
Sub DeleteBlanksInColB()
    Dim oRng As Range
    Dim jRows As Long
    Dim nCounter As Long
    
On Error GoTo ErrorHandler

    With Application
        .ScreenUpdating = False
        .Calculation = xlCalculationManual
    End With
    
    Set oRng = Intersect(ActiveSheet.Range("B:B"), ActiveSheet.UsedRange)
    
    jRows = oRng.Rows.Count

    For nCounter = jRows To 1 Step -1
        If Cells(nCounter, 2).Value2 = 0 Then
            Cells(nCounter, 2).EntireRow.Delete
        End If
    Next nCounter
    
ErrorExit:
    With Application
        .ScreenUpdating = True
        .Calculation = xlCalculationAutomatic
    End With
    
Exit Sub
    
ErrorHandler:
    MsgBox Err.Description, vbCritical
Resume ErrorExit

End Sub

schmagekie fucked around with this message at 06:48 on Jul 11, 2014

schmagekie
Dec 2, 2003

cadmaniak posted:

Is it possible to produce a graph with a dynamic rolling year range where the data is entered in columns rather than rows? e.g. A1 = Jan 14, B1 Feb 14 etc

I can get it to work fine for a rolling year period by rows with the formula below, adding new months onto the subsequent row but I'd like to do the same where I enter data for the next month in the next column to produce the same results.

=OFFSET(Sheet1!$A$1,COUNTA(Sheet1!$A:$A)-1,0,-MIN(chtLen,COUNTA(Sheet1!$A:$A)-1),1)

Most of the guides tell you how to do it by rows (which I can do), but I haven't been able to do it the opposite way..can anyone help?

Try replacing the $A:$A with $1:$1.

Are you using that for a dynamic named range? If so, charts require a reference to the sheet and name, such as, =Sheet1!DynamicNamedRange.

schmagekie
Dec 2, 2003

Chutch posted:

I made this code

=IF(I65="";0;'3.063'!$J$44)

and i want to drag/autofill for the cells down, but i want the IF function for the cell below to become like this:

=IF(I66="";0;'3.064'!$J$44)

I made the logical test look at the cell beneath (I66), but I can't make the value_if_false clause go for worksheet 3.064.

Am i making any sense and is there a way to do this?

You need to use the INDIRECT function.

I tested this in Excel, but typed it on my phone, so hopefully it works.
=IF(I65="",0,INDIRECT("'"&3+(ROW()-2)/1000&"'!J44"))

schmagekie fucked around with this message at 19:25 on Sep 16, 2014

schmagekie
Dec 2, 2003

Chutch posted:

I see what you did there. You made some kind of formula for calculating 3.004, right? As far as I understand that is not what I am looking for. Let me try this way, and tell me if I am wrong:

Here's the syntax:

=IF(logical_test;[value_if_true];[value_if_false]), where

logical_test is: I65="" which means "I65 cell is blank"
[value_if_true] is: 0 which means if I65 is blank then result is 0
[value_if_false] is '3.064'!$J$44 which means if I65 contains ANYTHING then it should result in the value from cell J44 (locked with $'s) from another worksheet named 3.064

I have a workbook with many worksheets with titles starting from 3.001 to approx 3.114. I can copy paste the above mentioned syntax and change '3.064' to '3.065', but thought there might be a simpler way by being able to drag and fill for all cells.

That code should work as intended if you paste it in row 65, then copy it where needed.
For I116, it should grab J44 from sheet 3.114.

schmagekie fucked around with this message at 21:23 on Sep 16, 2014

schmagekie
Dec 2, 2003

Isurion posted:

Index + match has the advantage that since the array you're selecting from is a cell reference you can drag the formula if you want to get the data from adjacent columns. With vlookup you have to either type in the column number by hand as an integer or use a helper row. Plus the match column can be to the right of the data column. Not really dealbreakers for vlookup but they are a couple nice quality of life things.

You can drag vlookup if you use the COLUMN() function, such as: =+VLOOKUP(D1,A:A,COLUMN()-4,0)

schmagekie
Dec 2, 2003

Nam Taf posted:

Can you name the column and refer to the name?

I'm not actually sure, I can't try this right now

You can take the column of what you're trying to grab. =VLOOKUP($A2,Data!$A:$J,COLUMN(Data!B2),0)
e: assuming the lookup range starts in col 1, otherwise you'll have to do a little thinking.

schmagekie fucked around with this message at 16:41 on Sep 23, 2014

schmagekie
Dec 2, 2003

Ragingsheep posted:

Is it possible to have frozen rows that "stack up" as you scroll down a sheet?

i.e. I want to freeze rows 1, 100 and 200 so that if I'm scrolling from row 1 downwards, only the first row is frozen but once I go past row 100, it's frozen underneath row 1 and once I go past row 200, I have 3 rows frozen at top.

Not really. See http://www.cpearson.com/excel/DetectScroll.htm
You could create a class to handle selection change events, but that would involve changing the active cell by clicking/arrow keys, or page down.

schmagekie
Dec 2, 2003

HisMajestyBOB posted:

I'm brand new to Excel VBA programming and I'm teaching myself through setting goals and trying to accomplish them through coding. However, I'm kinda stumped on how, exactly, to get values from a worksheet given certain criteria. For example, given a sheet with:

code:
Name	ID	Pay	Staff	Floor	Room	Clients	Cats
Jane	1	10	5	1	2	5	0
Jenny	2	5	1	1	1	3	0
Jose	3	8	0	1	2	6	0
Jones	4	15	0	2	4	12	0
Jack	5	12	8	2	5	6	15
Jethro	6	25	5	3	10	20	30
I'm able to get the Max or Min values for a given row or column and assign them to a variable using "MaxVar = WorksheetFunction.Max(Worksheets("Sheet1").Column(4)" or similar, but what I'd like to do is:

1. Given a particular value (ex. the ID number, or a unique value like Max # of cats), get the values under all columns for that particular person(s) and place them in select cells on another worksheet (say, variable "Target" defined as a range). So if I enter 1 into an input box for ID values, I want all of Jane's info to appear on another sheet in separate cells. I know I could just use vlookup, but I'm trying to work entirely through VBA. I also want to be able to pull out multiple people based on other critera, like "Staff" or "Cats" or whatever.

2. Given a variable "ChosenFloor", I want to randomly pick someone from that particular floor and display their info on another sheet. So if I enter 1, someone from floor 1 is randomly chosen and placed on the "CleanupDuty" sheet.

The only way I can think of to do this is through using Range.Find command, then making that cell Active and using Offset to gather information from the relevant cells in the row, but first, that doesn't seem right, and second, I've seen elsewhere that using Active and Offset are bad habits. The second goal is might be beyond a beginner like me, but I feel the first should be achievable and useful, but I can't figure out the best way to do that.

EDIT: Okay, I see that I can use Application.WorksheetFunction.VLookup when working with a unique ID, and that can also give me all of the other values. But how would I use it if I'm working with values that might be shared?

I do this sort of thing with the autofilter. Once the filter is applied, you can do something like, .autofilter.range.copy wksOutput.Range("A1").

I can post the exact code for this later, if needed.

schmagekie
Dec 2, 2003

Hughmoris posted:

I've been tackling a side project at work with Perl. I have a working solution but its a pretty shoddy hack. I'm thinking of re-writing the entire thing in Excel and VBA as a learning exercise. Outside of the taskscheduler, do these pseudo steps look possible entirely within Excel/VBA?

1. TaskScheduler to launch Workbook
2. Macro executes when Workbook is launched that:
- Copies pipe-delimited text file from network folder to local folder
- Loads that delimited file into workbook
- Parses delimited file, pulling out needed information and spreading it over 6 named worksheets
- Send each worksheet to a different specified network printer
- Bonus step: zip delimited file and move to different folder
- Close workbook and exit Excel

All of it's possible in VBA.

schmagekie
Dec 2, 2003

me your dad posted:

I've looked into a bit but I don't know if Consolidate will to work. It seems like the header data needs to be in the same order for this to work. Other instructions I saw indicate that there can be no blank rows, and I've got a lot of blank rows in my data.

Here's what I created to sort column headers... I changed it to rely on fewer functions, so hopefully it still works.
To use: create a sheet named "Master" with the correct column headings in row 1.
Run the code.
Each sheet will now have a corresponding sheet with the name "SheetXXX Sorted"

This requires a reference to the Microsoft Scripting Runtime library.
code:

    Sub SortColumns()
    Dim wkb             As Workbook
    Dim jWks            As Worksheet
    Dim wksMaster       As Worksheet
    Dim wksOutput       As Worksheet
    Dim rCorrect        As Range
    Dim rHeaders        As Range
    Dim dDictOrder      As Scripting.Dictionary
    Dim dDictOrderWrong As Scripting.Dictionary
    Dim jKey            As Variant
    Dim rCell           As Range
    
    With Application
        .ScreenUpdating = False
        .Calculation = xlCalculationManual
        .EnableEvents = False
    End With
    
    Set dDictOrder = New Scripting.Dictionary
    Set dDictOrderWrong = New Scripting.Dictionary
    
    Set wkb = ActiveWorkbook
    Set wksMaster = ActiveWorkbook.Sheets("Master")
    Set rCorrect = Intersect(wksMaster.Range("1:1"), wksMaster.UsedRange)

    'setup dictionary with correct order
    On Error Resume Next
        For Each rCell In rCorrect
            With dDictOrder
                .Add rCell.Value2, rCell.Column
            End With
        Next rCell
    On Error GoTo 0
        
    'iterate sheets
    For Each jWks In ActiveWorkbook.Worksheets
        If Not jWks Is wksMaster Then
            dDictOrderWrong.RemoveAll
            Set rHeaders = Intersect(jWks.Range("1:1"), jWks.UsedRange)
            For Each rCell In rHeaders
            
                If IsEmpty(rCell) Then
                    'if header is missing, give it a name
                    rCell.Value2 = "Field " & rCell.Column
                End If
                
                On Error Resume Next
                    With dDictOrderWrong
                        .Add rCell.Value2, rCell.Column
                    End With
                On Error GoTo 0
                
            Next rCell
                
            Set wksOutput = wkb.Sheets.Add
            ActiveSheet.Name = jWks.Name & " Sorted"
            
            For Each jKey In dDictOrderWrong.Keys
            
                If dDictOrder.Exists(jKey) Then
                    'copy column of jKey (item) to column of order(item)
                    jWks.Columns(dDictOrderWrong.Item(jKey)).Copy _
                        wksOutput.Columns(dDictOrder.Item(jKey))
                Else
                    'copy to end of destination
                    jWks.Columns(dDictOrderWrong.Item(jKey)).Copy _
                        wksOutput.Columns(WorksheetFunction.Max(FindEmptyColumn(wksOutput), dDictOrder.Count + 1))
                End If
                
            Next jKey
            
            'color it
            For Each rCell In wksOutput.Range(Cells(1, 1), Cells(1, FindEmptyColumn(wksOutput) - 1))
                If dDictOrder.Exists(rCell.Value2) Then
                    rCell.Interior.Color = vbGreen
                Else
                    'make it red and populate correct header
                    rCell.Interior.Color = vbRed
                    If rCell.Column <= dDictOrder.Count Then
                        rCell.Value2 = wksMaster.Cells(1, rCell.Column).Value2
                    End If
                End If
            Next rCell
            
        End If  'not order sheet
    Next jWks

    With Application
        .ScreenUpdating = True
        .Calculation = xlCalculationAutomatic
        .EnableEvents = True
    End With

    End Sub

    Public Function FindEmptyColumn(wks As Worksheet) As Long
    On Error Resume Next
        'ResetUsedRanges
        FindEmptyColumn = wks.Cells.Find("*", Range("A1"), xlFormulas, , xlByColumns, xlPrevious).Column + 1
    On Error GoTo 0

    FindEmptyColumn = WorksheetFunction.Max(FindEmptyColumn, 1)
    
    End Function

schmagekie
Dec 2, 2003

me your dad posted:

Thanks. I really appreciate it. I've decided to just do it manually. This is going to be a nightmare either way and I've settled into accepting this will be my day. This really falls outside of my normal job too, which adds insult to a poo poo situation.

Good luck! I give up after about 10 columns, hence writing that.

schmagekie
Dec 2, 2003
If you don't need the fancy bars, you could do something like =REPT("|",A1/78*100) and resize the column so that it would fit 100 characters.

schmagekie fucked around with this message at 20:11 on Oct 16, 2015

schmagekie
Dec 2, 2003

Daedleh posted:

Ahahah yeah their problem. That's not happening.

It's not just that only authorised users can view the report, but the report shows them personalised location data. They're not allowed to see other locations. There's nothing highly confidential in there which is why the security is allowed to be so relatively lax but they shouldn't easily have access to other locations.


It would be over 800 separate reports.

Each person also has access to their location and all sub-locations, which in the report they can currently select via drop-downs. Sending separate static reports means each person could have up to 150 reports emailed to them and each separate report would need its own distribution list.
It seems like you're maintaining some kind of list of what people should be able to see, so why not create one workbook for each person with only the data they should see and email it to them?

schmagekie
Dec 2, 2003

The rear end Stooge posted:

Is there a formula that I can use to display the value of a random cell from a range of cells? I have a list of items in text form and I'd like to be able to display a random entry from the list in another cell.

=INDEX(Range,RANDBETWEEN(1,ROWS(Range)),RANDBETWEEN(1,COLUMNS(Range)))

schmagekie
Dec 2, 2003

mirthdefect posted:

Can this be optimised in any way?
code:
Sub GetData()

Dim SheetCount As Integer
Dim RowCount As Integer
RowCount = 4

ClearData
SetDate

For SheetCount = 2 To (ActiveWorkbook.Worksheets.Count - 1)
    
    Sheets(SheetCount).Activate
    Range("H4:M7").Select
    Selection.Copy
    ActiveWorkbook.Sheets("Index").Select
    Cells(RowCount, 2).Select
    
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
        SkipBlanks:=False, Transpose:=False
        
        RowCount = RowCount + 6
        Next SheetCount


Cells(RowCount, 4) = "Total:"
Cells(RowCount, 5) = Application.Sum(Range(Cells(1, 5), Cells(RowCount, 5)))
... which does what I want, but there seems to be a bit of a lag after it pastes each block in. Also it seems silly to have two copy/paste steps (one for calculated values, one for formatting) but I can't work out how to do that in one.

This is for generating some billing/timesheet data for month end, which pulls a few cells from each individual sheet (except last, which is a template) to an index sheet, which I'll then send off to have invoices drawn up.

It can be optimized a lot. You rarely need to select, activate, copy, or paste.

code:

Sub GetData()
    Dim wkb As Workbook
    Dim wks As Worksheet
    Dim wksIndex As Worksheet
    Dim RowCount As Long

    RowCount = 4
    Set wkb = ActiveWorkbook
    Set wksIndex = wkb.Sheets("Index")

    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual

    ClearData
    SetDate

    'take H4:M7 from each sheet and put it on the index sheet
    For Each wks In wkb.Sheets
        If wks.Name <> "Index" And wks.Name <> "LastSheetName" Then 'change LastSheetName to its actual name
            wksIndex.Range(Cells(RowCount, 2), Cells(RowCount + 3, 7)).Value2 = wks.Range("H4:M7").Value2
            RowCount = RowCount + 6
        End If
    Next wks

    wksIndex.Cells(RowCount, 4) = "Total:"
    wksIndex.Cells(RowCount, 5) = Application.Sum(Range(Cells(1, 5), Cells(RowCount, 5)))

    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic

End Sub

schmagekie fucked around with this message at 19:28 on Mar 15, 2016

schmagekie
Dec 2, 2003

PRADA SLUT posted:

I'm looking for a VB script that will search a single column for a entry or entries (by name), and if it finds it, apply some format to the cell (font color or highlight it).

So if I wanted it to search for butt, it would highlight butt, thebutt, and butt 2k16.

It's easy enough to do in VBA, but just use the auto filter, search for butt, and go wild.

schmagekie
Dec 2, 2003

Richard Noggin posted:

I believe it's a holdover from those who cut their teeth on Lotus Notes, which started formulas with +. Excel happily handles this.

I've never used Lotus Notes, but always start formulas with +. It's easy to find.

schmagekie
Dec 2, 2003

Neddy Seagoon posted:

I'm trying to make an Excel function take a value and return multiple rows from a table line-by-line containing said value, but for the life of me I cannot figure out how to do it. Can anyone give me a code sample or point me to one online? Spent hours beating my head against this with various index-match and vlookup examples from Google :sigh:.

That sounds like some really advanced stuff that's meant for a VBA sub or Python rather than a function. Maybe this will help: https://colinlegg.wordpress.com/2014/08/25/self-extending-udfs-part-1/

schmagekie
Dec 2, 2003

SymmetryrtemmyS posted:

How do I turn this:


Into this:


Obviously this is a very small sample set. I have a few hundred columns to work with in the source data.

I'm open to VBA as a solution, but I am not very good with VBA. If you can provide some starting point or lead, I'd very much appreciate it!

This won't get you to the format you requested (which is awful), but it will be 1000% more manageable: http://dailydoseofexcel.com/archives/2013/11/19/unpivot-via-sql/

schmagekie
Dec 2, 2003

Scaramouche posted:

I used to know how to do this, but I've been stuck in customer facing land for too long lately. I've been given a longish sheet of products/services, that have quantities, and prices:
code:
Service |  Qty  |  Price
Anvil |  5 |  $50
Lamborghini | 2 |  $500000
Anvil | 4 | $55
I have no idea what the Services are, except they are consistent (e.g. Anvil is always Anvil, not sometimes Anvilz). For every unique service, I want to sum up both the Qty and the Price.

In database parlance it'd be pretty easy, something like:
code:
SELECT Service,SUM(Qty),SUM(Price)
    FROM BilledService
GROUP BY Service
But I'm not sure how to begin with a spreadsheet.

Pivot Table?

schmagekie
Dec 2, 2003

kumba posted:

So for this example, I need to shift all those timestamps into column B, and in column A, I need the value 1344 in rows 69 - 78, and the value 1842 in rows 80 - 97. The number of rows is going to fluctuate between employees. I'm assuming there's some way to look for the closest row above with a value that is not a timestamp in a column, and retrieve the ID from said row? I just can't wrap my head around how to accomplish that or if I'm making this too difficult and there's an obvious easy answer.

You want Excel to fill in the blank cells in column E with the value from the cell above. To do that,
Select column E only from the first ID to the last row you want an ID in. Hit CTRL+G to bring up the Go To menu, select Special, select Blanks, hit ok. Type the equals sign, hit the up arrow, then CTRL+Enter. The hard part is over, but now you'll want to change the formulas you just entered to values. Select column E, copy it, then Paste Values (Alt, H, V, V).

schmagekie
Dec 2, 2003

kumba posted:

sorry for double post, but another question: apparently I also need to convert the format the timestamp is in and I'm trying to figure out if there's a way to do it en masse and not 1 by 1?



rows 20 & 21 are in the proper format; rows 22 & 23 are not

I selected the whole column and formatted to custom (yyyy-mm-ddThh:mm:ss), but the values don't actually update until I actually edit the cell (e.g. F2 then Enter) and I'd really like to avoid having to do that for potentially thousands of cells. I saw somewhere that Shift + F9 should recalculate the whole tab, but that doesn't seem to be doing anything for me, and doing CTRL ALT F9 just recalculates formulas, it's not actually updating the format

What's the best way to accomplish this?

I think I've done this by selecting the cells that need to be corrected, opening the VBA editor (ALT+F11), and in the Immediate Window entering "selection.value2 = selection.value2", or multiplying those cells by 1 (enter 1 in any cell, copy it, select everything that needs to be corrected, paste special, multiply). ¯\_(ツ)_/¯

schmagekie
Dec 2, 2003

Sad Panda posted:

This feels more like a database and query, but I'm assuming there's a way to do it in Excel.

If I have a sheet which is master data, so for example

Name Class Email Score


And then I create another sheet which is the sheet for a specific class. How do I get it to pre-populate a table with the information from that master sheet? Students can move class and having to just update that in one place seems much nicer than having to manually move people from one sheet to another when they do.

Use a pivot table and filter it for whichever class you want. ¯\_(ツ)_/¯

schmagekie
Dec 2, 2003

AzureSkys posted:

I can't make a macro work to change the year to 2020 if the month is January or February. There's a work schedule that exports to excel and it makes all the years be 2019 even if the date is for next year in January or February. I then have to change all the January 2019 dates to be 2020.

I can use this one cell at a time, but can't figure out how to make it go through the whole column (column M) and change any if the month is 1 or 2.
code:
Sub AddYear()
Dim DateCell As Range
Set DateCell = selection
DateCell.Value = DateAdd("yyyy", 1, DateCell )
End Sub
My hope is to export the schedule from the website and then run the macro to fix the years.

You need to loop through the DateCell range.
Haven't tested the code, but that's the idea.

code:
Sub AddYear()
Dim DateCell As Range
Dim jCell as Range

Set DateCell = selection

For each jCell in DateCell
jCell.Value = DateAdd("yyyy", 1, jCell )
Next jCell

End Sub

Adbot
ADBOT LOVES YOU

schmagekie
Dec 2, 2003

Busy Bee posted:

I have some euro amounts in the following format:

6,923€
10,021€
etc.

But I want to shorten it to 6,9k€ and 10,0k€. How do I go about this? I looked at the following site and used the following format #,##0,“k” but it's only showing me rounded up so 7k€ and 10k€

https://wmfexcel.com/2015/03/14/show-number-in-thousand-k-or-in-million-m-by-using-custom-format/

#,##0.0,k€ may work.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply