Transfer data from sub-Sub to Function and back to main Sub - vbscript

I'm trying to write code that fill array in Function and than return result to main Sub. But this Function called from another Sub (sub-Sub). To understand how this will work I tried go step by step. And wrote this code:
Sub CATMain()
Dim val1
Call WalkDownTree() 'Here I call Sub to walk down Product Tree in CATIA
val1 = ParamTable(PartNumber, Name, Material, Texture, Color, Quantity)
For i=0 To UBound(val1)
MsgBox val1(i)
Next
End Sub
Sub WalkDownTree() 'Simplified code of the walk down tree to understand data transfer
PartNumber = "PartNumber"
Name = "Name"
Material = "Material"
Texture = "Texture"
Color = "Color"
Quantity = 1
Call ParamTable(PartNumber, Name, Material, Texture, Color, Quantity)
End Sub
Function ParamTable(PartNumber, Name, Material, Texture, Color, Quantity) 'Simplified array filing code. At original code I get all data from Part
Dim BOMTable(6,1000)
BOMTable(1,k) = PartNumber
BOMTable(2,k) = Name
BOMTable(3,k) = Material
BOMTable(4,k) = Texture
BOMTable(5,k) = Color
BOMTable(6,k) = 1
ParamTable = BOMTable
End Function
But I have error at line "MsgBox val1(i)": "Subscript out of range".
What did I miss?
And maybe exists more simple way to transfer array from Function to main Sub when Function fill from sub-Sub?

After some time I have a solution
This code works:
Dim PartNumber, Name, Material, Texture, Color, Quantity, k
Dim BOMTable(6,1000)
Sub CATMain()
Dim val1
Call WalkDownTree()
val1 = ParamTable(PartNumber, Name, Material, Texture, Color, Quantity, k)
For i = 1 To UBound(val1, 1)
For j = 1 To k-1
MsgBox val1(i,j)
Next
Next
End Sub
Sub WalkDownTree()
For k = 1 To 3
PartNumber = "PartNumber" & k
Name = "Name" & k
Material = "Material" & k
Texture = "Texture" & k
Color = "Color" & k
Quantity = 1
Call ParamTable(PartNumber, Name, Material, Texture, Color, Quantity, k)
Next
End Sub
Function ParamTable(PartNumber, Name, Material, Texture, Color, Quantity, k)
BOMTable(1,k) = PartNumber
BOMTable(2,k) = Name
BOMTable(3,k) = Material
BOMTable(4,k) = Texture
BOMTable(5,k) = Color
BOMTable(6,k) = Quantity
ParamTable = BOMTable
End Function

I would suggest not to be slacking in declaration of variables and even if it's not necessary for functioning. It is necessary for understanding.
The main global variable which holds all data should be declared on top
Option Explicit
Dim BOMData() As Variant
Then write the CATMain()
Sub CATMain()
Dim ItemCount As Integer 'This would be how many rows i will have in BOM or how many parts i will read i have to get this info from CATIA
ReDim BOMData(0 To ItemCount - 1, 0 To 5) As Variant 'This is making the collection
Dim Row As Integer
Dim Col As Integer
For Row = 0 To ItemCount - 1 'populate the BOM collection
Call WalkDownTree(Row)
Next
Dim TempStr As String
For Row = 0 To ItemCount - 1 'just write each row to msgbox
For Col = 0 To 5
TempStr = TempStr & BOMData(Row, Col) & " "
Next
Call MsgBox(TempStr)
TempStr=""
Next
End Sub
This is how could look the sub which populates the collection ... you are iterating through row or that could be items (products, parts etc)
Sub WalkDownTree(Row As Integer)
BOMData(Row, 0) = "PartNumber"
BOMData(Row, 1) = "Name"
BOMData(Row, 2) = "Material"
BOMData(Row, 3) = "Texture"
BOMData(Row, 4) = "Color"
BOMData(Row, 5) = 1
End Sub
The advantage of this solution could bring you simple excel export like this
Sub WriteToExcel()
Dim ExlApp As Excel.Application
Set ExlApp = GetObject(, "EXCEL.Application")
Dim ExlWorkBook As Workbook
Set ExlWorkBook = ExlApp.Workbooks.Open("C:\Test.xls")
Dim ExlSheet As Worksheet
Set ExlSheet = ExlWorkBook.Worksheets.Item(1)
ExlSheet.Range("A1").Resize((UBound(BOMData, 1) - LBound(BOMData, 1) + 1), (UBound(BOMData, 2) - LBound(BOMData, 2) + 1)).Value = BOMData
End Sub
EDIT
This is VBScript version. However i would suggest using VBA or VB .Net language for Catia if you want to seriously develop something. Using VBScript if not necessary is just torturing yourself
Dim BOMData()
Sub CATMain()
Dim ItemCount
ItemCount = 10 'how many items you have
ReDim BOMData (ItemCount - 1, 5)
Dim Row
Dim Col
For Row = 0 To ItemCount - 1 'populate the BOM collection
Call WalkDownTree(Row)
Next
Dim TempStr
For Row = 0 To ItemCount - 1 'just write each row to msgbox
For Col = 0 To 5
TempStr = TempStr & BOMData(Row, Col) & " "
Next
Call MsgBox(TempStr)
TempStr=""
Next
End Sub
Sub WalkDownTree(Row)
BOMData(Row, 0) = "PartNumber"
BOMData(Row, 1) = "Name"
BOMData(Row, 2) = "Material"
BOMData(Row, 3) = "Texture"
BOMData(Row, 4) = "Color"
BOMData(Row, 5) = 1
End Sub

Related

Compare value in 2 excel sheet and sort by descending in VBA

I'd like to use excel 2010 to realize a function to first compare values from 2 different Excel sheets and then sort them based on another column value.
For example:
In sheet 1, I've got:
Name Value
Test 1 100.5
Test 1 200.6
Test 1 300.3
Test 2 100.8
Test 2 200.6
Test 3 200.5
In sheet 2, I've got :
Name
Test 1
Test 1
Test 1
Test 3
what I want to achieve is if the name from sheet 1 is not in sheet 2, delete the whole line in sheet 1 and sort by descending the name based on the column value.
Desired:
Name Value
Test 1 300.3
Test 1 200.6
Test 1 100.5
Test 3 200.5
Here is what I get so far:
Sub test()
Dim wb As Workbook
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim i As Integer, j As Integer
Dim lastRow1 As Integer, lastRow2 As Integer
On Error GoTo 0
Set wb = ActiveWorkbook
Set ws1 = wb.Worksheets("Sheet1")
Set ws2 = wb.Worksheets("Sheet2")
lastRow1 = ws1.UsedRange.Rows.Count
lastRow2 = ws2.UsedRange.Rows.Count
For i = 2 To lastRow1
For j = 2 To lastRow2
If ws1.Cells(i, 1).Value <> "" Then 'This will omit blank cells at the end (in the event that the column lengths are not equal.
If InStr(1, ws2.Cells(j, 1).Value, ws1.Cells(i, 1).Value, vbTextCompare) < 1 Then
Rows(i).EntireRow.delete
Exit For
End If
End If
Next j
Next i
End Sub
Please suggest and help. thank you very much in advance.
I changed your code so it is working:
Sub test()
Dim wb As Workbook
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim i As Integer, j As Integer
Dim lastRow1 As Integer, lastRow2 As Integer
On Error GoTo 0
Set wb = ActiveWorkbook
Set ws1 = wb.Worksheets("Sheet1")
Set ws2 = wb.Worksheets("Sheet2")
lastRow1 = ws1.Cells(Rows.Count, 1).End(xlUp).Row 'last used cell in column A
lastRow2 = ws2.Cells(Rows.Count, 1).End(xlUp).Row 'last used cell in column A
Dim same As Boolean
same = False
For i = lastRow1 To 2 Step -1 'bottom to top
For j = 2 To lastRow2
Debug.Print ws1.Cells(i, 1).Value
Debug.Print ws2.Cells(j, 1).Value
If ws1.Cells(i, 1).Value <> "" Then 'This will omit blank cells at the end (in the event that the column lengths are not equal.
If ws1.Cells(i, 1).Value = ws2.Cells(j, 1).Value Then
same = True 'set True if match
End If
End If
Next j
If same = False Then 'if no match
Rows(i).EntireRow.Delete
End If
same = False
Next i
'sort
lastRow1 = ws1.Cells(Rows.Count, 1).End(xlUp).Row
Range("A2:B" & lastRow1).Sort key1:=Range("A2:A" & lastRow1), order1:=xlAscending, Header:=xlNo, key2:=Range("B2:B" & lastRow1), order2:=xlAscending, Header:=xlNo
End Sub
Still thinking about the rest of the answer, but in advance I would advise you to start at the bottom of the list (so from lastrow to the second row) The reason for this is that you are removing rows which your counter does not take into account. You may also want to look into the MATCH function in Excel to see if a certain value is used in a list instead of going through the whole list.

"integer out of range" error in a for next statement

I've gone nuts on this, and I'm sure the error is right in front of me, I just cant see it. appreciate all the help in debugging the statements below.
I have multiple slides in a ppt presentation. in some of the slides, there is a star shape, and a textbox with text "Hold" or "Yearly". I want to change the color of the star only if there is no textbox with "Hold" or "Yearly".
Sub Set_Star_Shape_Color_Green_Test()
Dim PPApp As Object ' As PowerPoint.Application
Dim PPPres As Object ' As PowerPoint.Presentation
Dim PPSlide As Object ' As PowerPoint.Slide
Dim iShpCnt1 As Integer
Dim iShpCnt2 As Integer
Dim iShpCnt3 As Integer
Dim iSlideCnt As Integer
Dim iBoxTopPos As Integer
Dim sHold As String
Dim sStar As String
Dim sTbox As String
Dim sTColor As String
Dim oShp As Shape
Set PPApp = GetObject(, "Powerpoint.Application")
Set PPPres = PPApp.ActivePresentation
Set PPSlide = PPPres.Slides _
(PPApp.ActiveWindow.Selection.SlideRange.SlideIndex)
iShpCnt0 = PPSlide.Shapes.Count
For iShpCnt1 = 1 To iShpCnt0 'PPSlide.Shapes.Count
iBoxTopPos = 260
' iSlideCnt = 2 removed
sHold = ""
sStar = ""
iShpCnt1 = 1
For iShpCnt1 = 1 To PPSlide.Shapes.Count
If iShpCnt1 <= PPSlide.Shapes.Count Then
**Set oSh = PPApp.ActivePresentation.Slides(iSlideCnt).Shapes(iShpCnt1) ' this is where i am getting the integer out of range error**
If oSh.Name.Text Like "*Hold*" Or oSh.Name.Text Like "*Yearly*" Then
sHold = oSh.Name
End If
If oSh.Name Like "*Star*" Then
sStar = oSh.Name
End If
End If
Next
For iShpCnt2 = 1 To iShpCnt0 ' this fixed the error
Set oSh = PPApp.ActivePresentation.Slides(iSlideCnt).Shapes(iShpCnt2)
If oSh.Name Like "*Star*" And sHold = "" Then
oSh.Fill.ForeColor.RGB = RGB(50, 205, 50) ' change the color to green
End If
Next
' go to next slide
If PPSlide.SlideIndex + 1 < PPPres.Slides.Count Then
PPApp.ActiveWindow.View.GotoSlide PPSlide.SlideIndex + 1
Set PPSlide = PPPres.Slides _
(PPApp.ActiveWindow.Selection.SlideRange.SlideIndex + 1)
End If
Next
' Clean up
Set PPSlide = Nothing
Set PPPres = Nothing
Set PPApp = Nothing
End Sub
You are setting the iterator to two.
For iSlideCnt = 1 To PPPres.Slides.Count
iBoxTopPos = 260
iSlideCnt = 2 <--- right here
It will go out of bounds if you have just one slide.

Excel copy/sort data while counting/removing duplicates

Ok so I've searched and searched and can't quite find what I'm looking for.
I have a workbook and what I'm basically trying to do is take the entries from certain ranges (Sheet1 - E4:E12, E14:E20, I4:I7, I9:I12, I14:I17, & I19:I21) and put them in a separate list on Sheet2. I then want the new list on Sheet2 to be sorted by how many times an entry appeared on Sheet1 as well as display the amount.
example http://demonik.doomdns.com/images/excel.png
Obviously as can be seen by the ranges I listed above, this sample is much smaller lol, was just having trouble trying to figure out how to describe everything and figured an image would help.
Basically I am trying to use VBA (the update would be initialized by hitting a button) to copy data from Sheet1 and put all the ranges into one list in Sheet2 that is sorted by how many times it appeared on Sheet1, and then alphabetically.
If a better discription is needed just comment and let me know, I've always been horrible at trying to describe stuff like this lol.
Thanks in advance!
Another detail: I cant have it search for specific things as the data in the ranges on Sheet1 may change. Everything must be dynamic.
I started out with this data
and used the following code to read it into an array, sort the array, and count the duplicate values, then output the result to sheet2
Sub Example()
Dim vCell As Range
Dim vRng() As Variant
Dim i As Integer
ReDim vRng(0 To 0) As Variant
Sheets("Sheet2").Cells.Delete
Sheets("Sheet1").Select
For Each vCell In ActiveSheet.UsedRange
If vCell.Value <> "" Then
ReDim Preserve vRng(0 To i) As Variant
vRng(i) = vCell.Value
i = i + 1
End If
Next
vRng = CountDuplicates(vRng)
Sheets("Sheet2").Select
Range(Cells(1, 1), Cells(UBound(vRng), UBound(vRng, 2))) = vRng
Rows(1).Insert
Range("A1:B1") = Array("Entry", "Times Entered")
ActiveSheet.UsedRange.Sort Range("B1"), xlDescending
End Sub
Function CountDuplicates(List() As Variant) As Variant()
Dim CurVal As String
Dim NxtVal As String
Dim DupCnt As Integer
Dim Result() As Variant
Dim i As Integer
Dim x As Integer
ReDim Result(1 To 2, 0 To 0) As Variant
List = SortAZ(List)
For i = 0 To UBound(List)
CurVal = List(i)
If i = UBound(List) Then
NxtVal = ""
Else
NxtVal = List(i + 1)
End If
If CurVal = NxtVal Then
DupCnt = DupCnt + 1
Else
DupCnt = DupCnt + 1
ReDim Preserve Result(1 To 2, 0 To x) As Variant
Result(1, x) = CurVal
Result(2, x) = DupCnt
x = x + 1
DupCnt = 0
End If
Next
Result = WorksheetFunction.Transpose(Result)
CountDuplicates = Result
End Function
Function SortAZ(MyArray() As Variant) As Variant()
Dim First As Integer
Dim Last As Integer
Dim i As Integer
Dim x As Integer
Dim Temp As String
First = LBound(MyArray)
Last = UBound(MyArray)
For i = First To Last - 1
For x = i + 1 To Last
If MyArray(i) > MyArray(x) Then
Temp = MyArray(x)
MyArray(x) = MyArray(i)
MyArray(i) = Temp
End If
Next
Next
SortAZ = MyArray
End Function
End Result:
Here is a possible solution that I have started for you. What you are asking to be done gets rather complicated. Here is what I have so far:
Option Explicit
Sub test()
Dim items() As String
Dim itemCount() As String
Dim currCell As Range
Dim currString As String
Dim inArr As Boolean
Dim arrLength As Integer
Dim iterator As Integer
Dim x As Integer
Dim fullRange As Range
Set fullRange = Range("E1:E15")
iterator = 0
For Each cell In fullRange 'cycle through the range that has the values
inArr = False
For Each currString In items 'cycle through all values in array, if
'values is found in array, then inArr is set to true
If currCell.Value = currString Then 'if the value in the cell we
'are currently checking is in the array, then set inArr to true
inArr = True
End If
Next
If inArr = False Then 'if we did not find the value in the array
arrLength = arrLength + 1
ReDim Preserve items(arrLength) 'resize the array to fit the new values
items(iterator) = currCell.Value 'add the value to the array
iterator = iterator + 1
End If
Next
'This where it gets tricky. Now that you have all unique values in the array,
'you will need to count how many times each value is in the range.
'You can either make another array to hold those values or you can
'put those counts on the sheet somewhere to store them and access them later.
'This is tough stuff! It is not easy what you need to be done.
For x = 1 To UBound(items)
Next
End Sub
All that this does so far is get unique values into the array so that you can count how many times each one is in the range.

Sort without moving formatting

I have an Excel table in which multiple rows are given different coloured backgrounds by VBA macros. These background colours should be locked to the rows. My problem is that when the table is sorted by one column or another the background colours move as the data is reordered.
Can I format in another way to stop this happening so that the cells remain locked?
The code I use to format is:
For Each Row In rng.Rows
If Condition Then
Row.Select
cIndex = ColourIndex(colour)
With Selection.Interior
.ColorIndex = cIndex
End With
End If
Next
An example of my table is like this:
EDIT: Extra Code
Sub Quota(ByVal Type As String)
Dim records As Long
Dim sht1 As Worksheet
Set sht1 = Worksheets("Sheet1")
Dim sht2 As Worksheet
Set sht2 = Worksheets("Sheet2")
records = sht1.Range("A1048576").End(xlUp).Row - 5
Dim rng As Range
Dim rngRowCount As Long
Dim rLastCell As Range
Dim i As Long
sht2.Activate
'Last used cell
Set rLastCell = sht2.Cells.Find(What:="*", After:=Cells(1, 1), LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False)
'All used columns except 1st
Set rng = sht2.Range(Cells(2, 1), rLastCell)
rng.Select
rngRowCount = rng.Rows.CountLarge
For i = 1 To rngRowCount
Dim valueAs String
Dim colour As String
Dim VarX As Long
Dim maxValue As Long
value= sht2.Cells(i + 1, 1).Value
colour = sht2.Cells(i + 1, 2).Value
If Type = "A" Then
VarX = sht2.Cells(i + 1, 3).Value
ElseIf Type = "B" Then
VarX = sht2.Cells(i + 1, 5).Value
End If
maxValue = (records / 100) * VarX
ColourRows value, colour, maxValue
Next i
End Sub
Sub ColourRows(value As String, colour As String, maxValue As Long)
Dim sht1 As Worksheet
Set sht1 = Worksheets("Sheet1")
sht1.Activate
Dim rng As Range
Dim firstSixRowsOnwards As Range
Dim lastColumn As Long
Dim usedColumns As Range
Dim usedColumnsString As String
Dim highlightedColumns As Range
Dim rngDataRowCount As Long
Dim performancevalueAs String
Dim cIndex As Integer
Dim count As Long
count = 0
Dim rLastCell As Range
'End row
rngDataRowCount = sht1.Range("A1048576").End(xlUp).Row
'First 6 rows
Set firstSixRowsOnwards = sht1.Range("A6:XFD1048576")
'Last column
lastColumn = Cells.Find("*", SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column
'Used Range
Set rng = sht1.Range(Cells(1, 1), Cells(rngDataRowCount, lastColumn))
'Used Columns
Set usedColumns = sht1.Range(Cells(1, 1), Cells(1048576, lastColumn))
Set rng = Intersect(rng, firstSixRowsOnwards, usedColumns)
For Each Row In rng.Rows
compareValue= Cells(Row.Row, 5)).Value
If (InStr(1, value, compareValue, 1) Then
Dim rowNumber As Long
Row.Select
If count < maxValue Then
cIndex = ColourIndex(colour)
With Selection.Interior
.ColorIndex = cIndex
End With
count = count + 1
Else
cIndex = 3 'red
With Selection.Interior
.ColorIndex = cIndex
End With
End If
End If
Next
End Sub
I believe that if you select your data by column and then sort (instead of a row limited range) then formatting will follow.
EDIT:
If you want to lock the formatting then use conditional formatting that is based on row number, e.g. ROW() = x or ROW() = range of values...
Tested: Use conditional formatting by formula set rule such as =ROW()=3 make sure excel does not double quote it for you, apply this to the entire data range. Row 3 will then always be formatted as you set here.
Setting in vba
Sub test()
Range("A3").Select
With Range("A3")
.FormatConditions.Add Type:=xlExpression, Formula1:="=ROW()=3"
.FormatConditions(1).Interior.ColorIndex = 46
End With
End Sub
Can be done with CF, for example (top rule is >11):
Edit - I inadvertently left out one rule
the second down below uses =ROW($A1)=11:
Here we go:
In this case, what I would do it one of the two things:
Conditional formatting. Needs lot of logics and manual steps so let us leave it.
A macro: Whenever you sort the data, please fire the following function
Sub Option1()
Dim row As Range
Dim rowNum As Integer
Dim tRange As Range
'set range here: in your example, it is A2:D11
Set tRange = ActiveSheet.Range("A2:D11")
'clear colors
tRange.ClearFormats ' clears the previous format
rowNum = 1
For Each row In tRange.Rows
Select Case rowNum
Case 1, 2
row.Interior.Color = RGB(255, 255, 0) ' 1 and 2nd will be yellow
Case 3, 4
row.Interior.Color = 255 ' 3rd and 4th row will be red
Case 5, 6
row.Interior.Color = RGB(0, 0, 255) ' 5 and 6th row will be blue
Case Else
row.Interior.Color = RGB(0, 255, 0) '' all the bottom row would be a Green row
End Select
rowNum = rowNum + 1
Next row
End Sub
Does it help?

MS Visual Basic how to sort 1 array and return index for second array?

the language I am looking is MS Visual Basic.
How can I sort an array and change other arrays accordingly (using an index?)
I was searching, but couldnt find any stuff on that. Any help is greatly appreciated!!!
e.g. Sort array BirthArray and change the order of Array1 and ID accordingly?
Array1 = 'John', 'Christina','Mary', 'frediric', 'Johnny','billy','mariah'
BirthArray = 1998, 1923, 1983,1982,1924,1923,1954
ID = 12312321, 1231231209, 123123, 234324, 23423, 2234234,932423
Dim Array() As String
Dim BirthArray() As Integer
Dim ID() As Integer
Thanks a lot!
You should make a class to hold the values, put a collection of the classes into a List, then sort the the list using a lambda expression:
Public Class Info
Public Property Name As String
Public Property BirthYear As Integer
Public Property ID As Integer
Public Sub New()
End Sub
Public Sub New(sName As String, wBirthYear As Integer, wID As Integer)
Me.New
Me.Name = sName
Me.BirthYear = wBirthYear
Me.ID = wID
End Sub
End Class
Public Sub DoSort()
Dim cRecords As New System.Generic.List(Of Info)
cRecords.Add(New Info('John', 1998, 12312321)
' ToDo: Add more records
cRecords.Sort(
Function (ByVal oItem1 As Info, ByVal oItem2 As Info)
Return oItem2.BirthYear.CompareTo(oItem1.BirthYear)
End Function)
End Sub
The proposed soluton below (based on your VBA tag).
creates a 2D array from 3 single arrays (as suggested by Jesse)
uses Redim Preserve to add a fourth dataset "NewData" to a 2D array "ArrayMaster"
creates a temporary worksheet, dumps "ArrayMaster" to it, sorts by "Newdata" (ascending order) to create a sorted array, "ArrayMaster2"
deletes the working sheet
Excel is very efficient at sorting, so this method provided an easy and quick way for a sort (or multi level sort)
You could use a bubble sort technique if Excel wasn't available for the sheet dump/sort
Option Base 1
Sub ComboArray()
Dim ws As Worksheet
Dim Array1()
Dim Birthday()
Dim ID()
Dim NewData()
Dim ArrayMaster()
Dim ArrayMaster2()
Dim lngRow As Long
Dim lngCalc As Long
Dim lngCheck As Long
Birthday = Array(1998, 1923, 1983, 1982, 1924, 1923, 1954)
Array1 = Array("John", "Christina", "Mary", "frediric", "Johnny", "billy", "mariah")
ID = Array(12312321, 1231231209, 123123, 234324, 23423, 2234234, 932423)
ReDim ArrayMaster(1 To UBound(Array1, 1), 1 To 3)
'Create 2D MasterArray
For lngRow = 1 To UBound(Array1, 1)
ArrayMaster(lngRow, 1) = Array1(lngRow)
ArrayMaster(lngRow, 2) = Birthday(lngRow)
ArrayMaster(lngRow, 3) = ID(lngRow)
Next
NewData = Array(1, 3, 5, 7, 2, 4, 6)
'Check if new field is longer than overall array
If UBound(NewData, 1) > UBound(ArrayMaster, 1) Then
lngCheck = MsgBox("New field exceeds current array size, proceeding will drop off excess records" & vbNewLine & "(Press Cancel to end code)", vbOKCancel, "Do you want to proceed?")
If lngCheck = vbCancel Then Exit Sub
End If
'Add NewData field
ReDim Preserve ArrayMaster(UBound(ArrayMaster, 1), UBound(ArrayMaster, 2) + 1)
For lngRow = 1 To UBound(NewData, 1)
ArrayMaster(lngRow, UBound(ArrayMaster, 2)) = NewData(lngRow)
Next
With Application
.ScreenUpdating = False
.DisplayAlerts = False
lngCalc = .Calculation
End With
'Create working sheet, dump MasterArray and sort by Newdata (position 4 = cell D1)
Set ws = Worksheets.Add
ws.[a1].Resize(UBound(ArrayMaster, 1), UBound(ArrayMaster, 2)).Value2 = ArrayMaster
ws.UsedRange.Sort ws.[d1], xlAscending
'Create our sorted array MasterArray2, now with NewData(1,2,3,4,5,6,7)
ArrayMaster2 = ws.[a1].Resize(UBound(ArrayMaster, 1), UBound(ArrayMaster, 2)).Value2
ws.Delete
'cleanup working sheet
With Application
.ScreenUpdating = True
.DisplayAlerts = True
.Calculation = lngCalc
End With
End Sub

Resources