Sort sections alphabetically in Powerpoint using VBA - vba

I have a big PowerPoint file with many sections and I keep adding some.
I am looking for a way to sort my sections by alphabetical order.
I am sure it's doable using VBA but my knowledge are limited and I couldn't find a similar code to adapt.
Thanks a lot for your help!

This is based on a classic array-sort-logic - but applied to the sections.
No idea if this is a performance issue if you have a lot of sections.
Sub sortSections()
Dim sp As SectionProperties
Set sp = ActivePresentation.SectionProperties
Dim cntSections As Long
cntSections = sp.Count
Dim i As Long, j As Long
For i = 1 To cntSections - 1
For j = i + 1 To cntSections
If UCase(sp.Name(i)) > UCase(sp.Name(j)) Then
sp.Move j, i
End If
Next
Next
End Sub

Related

For loop not capturing all values in SAP

new to SAP but have done some VBA programming.
I need to automate some things in SAP using Excel VBA but I am starting with baby steps and getting stumped.
All I want to do is copy data from a column in SAP (table already open) into an array. Sounds simple. However it starts off well, but never finishes properly. I have a table that has 306 rows. It has gotten stuck at 85, 127, and 178. Not sure if these values mean anything. What's even more puzzling to me is why does it return a value of 0000000127?? I've been looking for an answer for hours.
Running SAP Complex and Excel 2013. Cannot locate SAPfewse.ocx either. I've enabled almost all references in VBA Developer window. Any help/ideas would be much appreciated! I'm hoping it is something obvious.
Set Table = Session.FindById("wnd[0]/usr/cntlDISASSEMBLY_ALV/shellcont/shell")
Dim rows As Long
Dim arrRow() As Variant
Dim colName As String
Dim rowCount As Double
rows = Table.rowCount - 1
ReDim arrRow(rows)
colName = "ZZMRO_CHA"
For j = 0 To rows
arrRow(j) = Table.GetCellValue(j, colName)
Next
Array watch output - "completed" loop
You could try the following:
...
For j = 0 To rows
arrRow(j) = Table.GetCellValue(j, colName)
If j Mod 32 = 0 Then Table.currentCellRow = j
Next
...
Regards, ScriptMan

Filtering out Area codes in Excel by VBA

need some assistance. It's been a very long time since I've done scripting/coding and really rusty now.
Issue: I have a spreadsheet(Excel Visual Basic) that contains call(s) over a month(Over 30k records). My goal is to filter out calls that have specific area codes (toll free, local calls...etc) and calculate how much they owe from calling long distance.
Additionally, this is a retirement home and the end-user(s) do not enter phone numbers correctly. I need to either strip 3-4 digits at the start of numbers..
Example: 1800-XXX-XXXX or 800-XXX-XXXX | 1605-XXX-XXXX
Here's the code I currently have, I'm lost on how to incorporate the 3-4 digits in the area and have it parse each record in Column H by the first 3-4 digits
Phone numbers are stored in Column H
Array TFL will store all the area codes I need to filter out.
Sub CleanEntry()
Dim i As Integer
Dim TFL As Variant
TFL = Array("1800", "1877")
For i = Sheet1.UsedRange.Rows.Count To 1 Step -1
If Left(Cells(i, "H"), 4) Like TFL(i) Then
Sheet1.Rows(i).EntireRow.Delete
End If
Next
End Sub
I'd personally use a regular expression for this:
Sub CleanEntry()
Dim i As Integer
Dim filter As New RegExp
filter.Pattern = "^1?(8(77|00))|605" 'Or whatever else you need to match.
For i = Sheet1.UsedRange.Rows.Count To 1 Step -1
If filter.Test(Trim$(Cells(i, "H").Value)) Then
Sheet1.Rows(i).EntireRow.Delete
End If
Next
End Sub
Note: You'll need to add a reference to Microsoft VBScript Regular Expressions 5.5.

Is it possible to add cases to a Select Case based on the number of entries in a table?

I've been messing around with VBA in Excel a bit recently; and as a small project for myself, I'm trying to create a "draw names from a hat" sort of macro.
I began by generating a random number, and then choosing which entry from a Table (i.e. ListObject) would be selected using a case statement. The problem with this is that it only works of the number of Table entries is always the same.
So my question (probably a ridiculous one) is: is it possible at all to generate a dynamic 'Select Case' block, where the number of cases on the block is based on the number of entries in the Table?
Thanks.
-Sean
Edit: To clarify: what I am trying to do, exactly, is this:
I generate a random number, i, from 1 to n=10*(number of Table entries). After this, I want to display, in a cell, one of the table entries based on the random number.
Ideally, the code would work similarly to this:
if i = 1 to 10 then choose event 1
if i = 11 to 20 then choose event 2
if i = 21 to 30 then choose event 3
...
if i = (n-9) to n then choose event (n/10)
I hope this helps to clarify the goal of the code.
From our comments here is something you can use:
Sub random()
Dim used_rows As Integer
Dim random As Integer
Dim cell_array() As Integer
used_rows = Sheet1.UsedRange.Rows.Count
ReDim cell_array(used_rows)
For i = 1 To used_rows
cell_array(i - 1) = Cells(i, 1)
Next
random = Int(Rnd * (used_rows))
MsgBox cell_array(random)
End Sub
You can go ahead and change MsgBox to whatever you like, or set like Cell(1,4).Value = cell_array(random), or however you'd like to proceed. It will be based off the number of rows used. Though depending on how you implement your spreadsheet the code might have to be changed a bit.
Here's the update code from the suggestions from the comments. Also remember to use Randomize() in your form initialization or WorkBook Open functions.
Sub random()
Dim used_rows As Integer
Dim random As Integer
'Multiple ways to get the row count, this is just a simple one which will work for most implementations
used_rows = Sheet1.UsedRange.Rows.Count
random = Int(Rnd * (used_rows))
'I use the variable only for the reason that you might want to reference it later
MsgBox Cells(random, 1)
End Sub
This assumes that by "table" you mean "Table with a capital T", known in VBA as a ListObject:
Sub PickRandomTens()
Dim lo As Excel.ListObject
Dim ListRowsCount As Long
Dim RandomNumber As Long
Dim ListEvent As String
Dim Tens As Long
Set lo = ActiveSheet.ListObjects(1)
ListRowsCount = lo.DataBodyRange.Rows.Count
RandomNumber = Application.WorksheetFunction.RandBetween(10, ListRowsCount * 10)
ListEvent = lo.ListColumns("Data Column").DataBodyRange.Cells(Int(RandomNumber / 10))
MsgBox "Random number: " & RandomNumber & vbCrLf & _
"Event: " & ListEvent
End Sub

excel vba moving non-contiguous range selection to an array

In the situation where the user select two non-contiguous column ranges i wrote the following:
Dim count long
Dim points variant
Dim i long
Set user_range = ActiveWindow.RangeSelection
count = user_range.count / 2
ReDim points(1 To count, 1 To 2)
For i = 1 To count
MsgBox "value is" & user_range.Areas.Item(1).Value(i,1)
points(i, 1) = user_range.Areas.Item(1).Value(i,1)
points(i, 2) = user_range.Areas.Item(2).Value(i,1)
Next i
But i get an object error when i try this. Am i indexing Value wrong?
This should work right? Is there an easier way to do this?
Any help is greatly appreciated!
Thanks,
Russ
I'm afraid your code does not compile. First of all, you need to declare your variables correctly. You should also use Option Explicit.
Option Explicit
Dim count As Long
Dim points As Variant
Dim i As Long
Dim user_range As Range
The count and ReDim lines are OK, but you are assuming that the two selections are both the same size. Will that always be the case?
Then I'm not sure what it is you want to do, but I'm guessing you just want to save the values in user_range into points.
You need to adress them a bit different:
points(i, 1) = user_range.Areas(1).Cells(i, 1).Value 'Selection 1
points(i, 2) = user_range.Areas(2).Cells(i, 1).Value 'Selection 2

Excel VBA Length-1 In a Range

I recently got into Excel macro development after a long time of not having the need to.
I have one column with two-hundred rows where each row has a value. I wrote a loop to iterate to each row value, read the current value and then write the value back minus the last character.
Here is some actual (and pseudo) code of what I wrote.
Dim theRow as Long
Dim totRow as Long
Dim fooStr as String
theRow = 2 'we begin on the second row of the colummn
totRow = 201 'there are 200 values
For theRow = 2 to totRow
fooStr = WorkSheets(DestSheet).Cells(theRow,"A").Formula 'read the cell value
fooStr = Left(fooStr,Len(fooStr)-1 'subtract the last character from the value
Cells(theRow,1).Value = fooStr 'write the value back
Next theRow
After I did some reading I learned that it is best practice to read and write values using a Range. Is it possible to rewrite what I am doing using a Range so it willl go faster.
Here is what I came up with so far.
Range("A2:A201").Value = Len(Range.Left("A2:A201").Value)-1
However, this doesn't work.
Any clues on how to do this if this is indeed possible?
Thanks for any tips.
If you want maximum performance (you don't need it for 200 rows, but...) you have to minimize the number of reads and writes (mostly writes) to ranges. That means reading the whole range into an array, manipulating the array, then writing it back to the range. That's one read and one write compared to 200 in a loop. Here's an example.
Sub RemoveLastChar()
Dim vaValues As Variant
Dim i As Long
vaValues = Sheet1.Range("A2").Resize(200).Value
For i = LBound(vaValues, 1) To UBound(vaValues, 1)
vaValues(i, 1) = Left$(vaValues(i, 1), Len(vaValues(i, 1)) - 1)
Next i
Sheet1.Range("A2").Resize(UBound(vaValues, 1), UBound(vaValues, 2)).Value = vaValues
End Sub
You could do something like
Sub StringTrim()
Dim xCell as Range
Range("A1:A201").Select
For Each xCell in Selection
xCell.Value = Left(xCell.Value, Len(xCell.Value) - 1)
Next
End Sub
I don't know what kind of speed improvements you are seeking, but that would also do the job.
You might know this already but putting Application.ScreenUpdating = False at the top of your code can speed it up significantly (unless you like to watch everything flash by as the script works). You should reset the value to True at the end of your code.