1

I'm trying to automate excel modificaions.

The process works like this:

  1. The Excel list gets created.
  2. It needs to be manually processed by an employee (removing images, sorted alphabetically, etc.)
  3. The list gets converted into a csv file.
  4. CSV gets uploaded and processed.

Now I would like to automate this process as much as possible. I don't have any experience working with VBA or Excel macros.

So far i've been able to scramble a few different scripts together to get halfway, but I haven't been able to get these two functions working. I've been able to remove all the bloat at the top (not at the bottom yet), remove empty rows and remove unused columns.

I can't post the contents of the sheet itself because of privacy reasons, but the structure of the sheet looks like this:

| Name | Cost |

| Mark Renner (mare) | €200,- |

Question

I want to extract the 4 letter codes and replace them for the full names so only the 4 letter code remains in the cell.

Also I would like the list to be sorted alphabetically. The range of the sheet differs per day so there is no fixed ammount of cells.

There is nothing else on the sheet you need to worry about. I can provide more information if necessary.

It would be tremendous if someone is able to help me with this.

Thanks in advance!

Edit:

Here is some more requested information.

Table example after current script

This is the script I am currently using to remove all the bloat. I'm sure it's not perfect but it does the job for now.


    Sub run()
    Call testvba
    Call DeleteRowWithContents
    Call usedR
    End Sub

    Sub testvba()
    Dim i As Integer
    For i = 1 To 21
    Rows(1).EntireRow.Delete
    Next i

    For i = 1 To 10
    Columns(4).EntireColumn.Delete
    Next i

    Dim shape As Excel.shape
    For Each shape In ActiveSheet.Shapes
    shape.Delete
    Next


    End Sub

    Sub DeleteRowWithContents()
    Last = Cells(Rows.Count, "A").End(xlUp).Row
    For i = Last To 1 Step -1
        If (Cells(i, "A").Value) = "User" Then
            Cells(i, "A").EntireRow.Delete
        End If
    Next i
    End Sub

    Sub usedR()
    ActiveSheet.UsedRange.Select
    'Deletes the entire row within the selection if the ENTIRE row contains no      data.
    Dim i As Long
    'Turn off calculation and screenupdating to speed up the macro.
    With Application
    .Calculation = xlCalculationManual
    .ScreenUpdating = False
    'Work backwards because we are deleting rows.
    For i = Selection.Rows.Count To 1 Step -1
    If WorksheetFunction.CountA(Selection.Rows(i)) = 0 Then
    Selection.Rows(i).EntireRow.Delete
    End If
    Next i
    .Calculation = xlCalculationAutomatic
    .ScreenUpdating = True
    End With
    End Sub `

Here is the table before the script:

Before

SOLUTION:

I used Schalton's code for extracting the 4 letter code.

I ended up using this line of code to alphabetize the records:


    Sub Alpha()
    Dim fromRow As Integer
    Dim toRow As Integer
    fromRow = 1
    toRow = ActiveSheet.UsedRange.Rows.Count
        ActiveSheet.Rows(fromRow & ":" & toRow).Sort Key1:=ActiveSheet.Range("A:A"), _
           Order1:=xlAscending, Header:=xlNo, OrderCustom:=1, _
           MatchCase:=False, Orientation:=xlTopToBottom
    End Sub
Alterlai
  • 55
  • 7
  • S.O. isn't a distributor of code ready to use... you wrote:2. It needs to be manually processed by an employee. Well, start macro recorder and process your data, then post here your code and we help you to manipulate this code – Fabrizio Dec 02 '15 at 09:55
  • @Fabrizio Well there is a slight issue. At the moment, a few of the steps requires the employee to save the file as CSV and open it in notepad to replace the ()'s with ;'s so that the 4 letter code can be extracted. I can record a macro up to that point if that helps. – Alterlai Dec 02 '15 at 10:11
  • please input here the string that guy manipulate in notepad, I'm incredulous... can be that this manipulation (if is necessary) will be processed by VBA – Fabrizio Dec 02 '15 at 10:35
  • The whole thing goes like this: - Remove unnecessary text and images - Save as CSV. - Open in notepad. Find and replace ( with a ; . Find and replace ) with nothing. - Save again and open in excel. What ends up happening is that the 4 letter code is now seperated from the name and we are able to remove the name column and just keep the 4 letter code. – Alterlai Dec 02 '15 at 10:39
  • The whole thing is unwieldy, that's why i want to automate the process. – Alterlai Dec 02 '15 at 10:42
  • the whole thing is crowds, for this I ask you an exampe of your sheet, (ok for privacy) I just need one record with fancy names, you can do one print screen and update your tread, othewise I can't help you – Fabrizio Dec 02 '15 at 10:50
  • I hope the added info is of use. – Alterlai Dec 02 '15 at 11:12
  • more or less, post also the table before script. I want to evitate to copy the tab into notepad – Fabrizio Dec 02 '15 at 11:19
  • If I see the two img, cells.value in the colum A is the same (ok you delete header from original file) but if the imgbefore.cell("A24") is = imgafter.cell("A1") what append in notepad?!?!? – Fabrizio Dec 02 '15 at 11:49
  • Nothing has happend in notepad just yet in either of the two images. At this point I would open the file in notepad and replace all the ()s with ; so that once opened in excel again, the 4 letter code would be in a column between the name and costs. Then the name column is removed and the code and cost column get moved over to the left. Now we're left with just the 4 letter code and the cost. – Alterlai Dec 02 '15 at 12:19

1 Answers1

0

To get the 4 letter code you can search for the "(" and cut the string down

Something like this will get you to the code, you could use regedit but that seems like overkill

Sub ReplaceName()
LastRow = Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
For r = 2 to LastRow 'assumes data starts in row 2 with header in row 1
    if Cells(r,1).value = "" then goto Nextr 'skips blanks
    CurrentString = Cells(r,1).value 'assumes the names are in column 1
    'At this point CurrentString = "Mark Renner (mare)"
    CurrentString = Right(CurrentString,len(CurrentString)-instr(1,CurrentString,"("))
    'At this point CurrentString = "mare)"
    CurrentString = left(CurrentString,instr(1,CurrentString,")")-1)
    'At this point CurrentString = "mare"
    Cells(r,1).value = CurrentString
Nextr:
Next r
End Sub

As far as putting it in alphabetical order, there are two ways that come to mind

  1. Move all of the values into an array then iterate through the array and sort them
  2. Create a filtered range and filter is

the second option is MUCH easier, and for what you're doing I think it's probably fine. It'll look something like this:

With data that looks like this (in cells A1 to B6):

Name    Cost
Tom     149
Dick    272
Harry   186
Moe     292
Larry   377

I'd do something like this:

Sub SortAlpha()
LastRow = Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row

Range(Cells(1,1),Cells(LastRow,2)).select 'selects the data and headers
Selection.AutoFilter 'Adds Filter
ActiveWorkbook.ActiveSheet.AutoFilter.Sort.SortFields.Clear

Range(Cells(1, 1), Cells(LastRow, 1)).Select 'selects name column

'filters alpha
ActiveWorkbook.ActiveSheet.AutoFilter.Sort.SortFields.Add Key:=Selection _
    , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
    xlSortNormal
With ActiveWorkbook.ActiveSheet.AutoFilter.Sort
    .Header = xlYes
    .MatchCase = False
    .Orientation = xlTopToBottom
    .SortMethod = xlPinYin
    .Apply
End With

Range(Cells(1,1),Cells(LastRow,2)).select 'selects the data and headers
Selection.AutoFilter 'Removes Filter
End Sub

That'll Give you this:

Name    Cost
Dick    272
Harry   186
Lary    377
Moe     292
Tom     149

As Far as cleaning the data I usually do a couple of things when I have data tables that are really messy

Start Here:

 1. iterate through the range and remove all merges
 2. unwrap all of the text
 3. delete all pictures
 4. Delete any blank Rows or columns

I like this code for finding the last row:

LastRow = Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row

You can modify it to find the last column

LastCol = Cells.Find("*", SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column

Then you can loop through your whole sheet cell by cell, or as a range Cell by Cell: (I use this to unmerge the cells - can be slow)

For r = 1 to LastRow
    For c = 1 to LastCol
       'Do Stuff
       Cells(r,c).UnMerge 'or Cells(r,c).MergeCells = False
    Next c
Next r

or as a range: I use this for unwrapping the text

Range(Cells(1,1),Cells(LastRow,LastCol)).WrapText = False

To delete the pictures I use this code: Deleting pictures with Excel VBA

Dim shape As Excel.shape
For Each shape In ActiveSheet.Shapes
    shape.Delete
Next

This seems like it would work for saving the csv if you wanted to automate that also:

Saving excel worksheet to CSV files with filename+worksheet name using VB

I'd re-resize all of your rows and columns, rows to their default and columns to the fit: Unfortunately I haven't found a great way to do the rows without a range string so my code is a little messy:

RowRange = "1:" & LastRow
Rows(RowRange).RowHeight = 12.75

Columns are about the same, but worse because they're not numbered

ColStart = Cells(1,1).Address
ColEnd = Cells(1,LastCol).Address
ColStart = left(ColStart,len(ColStart)-1)
ColEnd = left(ColEnd,len(ColEnd)-1)
ColStart = Replace(ColStart,"$","")
ColEnd = Replace(ColEnd,"$","")
ColRange = ColStart & ":" & ColEnd
Columns(ColRange).EntireColumn.AutoFit

you could alternatively just make it significantly large, but where's the fun in that?

Columns("A:ZZ").EntireColumn.AutoFit
Community
  • 1
  • 1
Schalton
  • 2,867
  • 2
  • 32
  • 44
  • You caught me while I was drinking my coffee so I just brain dumped on your project, if you want further help fell free to contact me here: https://www.fiverr.com/navenine/write-vba-code-or-create-userforms-for-you Deleting the empty rows and columns is less trivial and it's about time for me to get to work. Hope that helps -E – Schalton Dec 02 '15 at 12:18
  • Hey Schalton, Thanks a LOT for the response, it was very helpfull. I found one issue when running the first script. It gave me the error: "Next missing For". It's referring to "Next r ". Like i mentioned earlier. I have no experience in VBA so it might be a really easy fix. As for the alphabetical sorting, it worked perfectly. Also the tips for cleaning the data were really usefull! – Alterlai Dec 02 '15 at 12:31
  • Oops, I made the change `Next r: to Nextr:` that should do it. That's a label to allow the code to skip the string edits when the value is empty. No worries, glad to help. – Schalton Dec 02 '15 at 12:34
  • In your data you have more than 2 columns, where I have a "2" for the number of columns you can change that by adding the "LastCol" calc, or by making it 3,4,5.... if you want to sort more than just the two columns, – Schalton Dec 02 '15 at 12:36
  • Thanks for your response, after editing the script i'm left with: mare) – Alterlai Dec 02 '15 at 12:41
  • Yikes, that's what I get for not testing that script replaced `CurrentString = left(CurrentString,instr(1,CurrentString,")")-1)` The -1 will remove the last digit – Schalton Dec 02 '15 at 12:43
  • It's working down to the T! There is one tiny issue that's still left. When using the SortAlpha function, it the top record is not affected. When calling the function, the data start at A1. I've tried changing it myself but I wasn't able to find it without breaking anything :( – Alterlai Dec 02 '15 at 13:10
  • Yeah that sort method requires a header -- or a blank cell above, so you'd need to insert a row above or sort it before deleting the mess at the top something like `Range("A1").EntireRow.Insert: Call SortAlpha: Rows(1).EntireRow.Delete` (I'm writing this from my phone, but that should give you a general idea). – Schalton Dec 02 '15 at 14:23
  • I got it working using some other guy's code. If you're interrested I can send it to you but it's a bit too long to post it here in the comments :) Anyway, Thanks a lot for your help man! – Alterlai Dec 02 '15 at 14:35