'********************************************************************************************************** ' Name: addColumns ' Author: mielk | 2014-09-11 ' ' Description: Function to add the specified number of columns to the given array. ' ' Parameters: ' arr Source array. ' It must have exactly two dimensions, if other array or non-array is given to this ' function, exception will be thrown. ' howManyColumns The number of columns to be added. ' startIndex Optional parameter of Integer type. ' * It defines at what index new columns should be put into the source array. ' * If the number of start index is greater than the total number of columns in the ' source array, new columns are added at the end of the source array. ' * If 0 is passed as [startIndex], columns are added at the beginning of the source ' array. ' * If negative value is given, columns are counted from the end of the source array, ' i.e. if you give -2 as [startIndex] parameter, new rows will be added after the ' second column from the end. ' * If negative index is passed to the function and its absolute value exceeds the ' total number of columns in the source array, new columns are added at the ' beginning of the source array. ' Default value for this parameter is -1, that means new columns will be added ' at the end of the source array. ' ' ' Returns: ' Variant Source array with as many additional column as parameter [howManyColumns] added ' at the index defined in [startIndex] parameter. ' ' ' ' Exceptions: ' NotArrayException Thrown if the given parameter [arr] is not an array. ' NotDefinedArrayException Thrown if the given paremeter [arr] is an array, but it has not been ' initialized yet. ' DimensionsException Thrown if the array passed to this function has less or more than two ' dimensions (only 2D arrays can be filtered by this function). ' ' ' --- Changes log ----------------------------------------------------------------------------------------- ' 2014-09-11 mielk Function created. '********************************************************************************************************** Public Function addColumns(arr As Variant, howManyColumns As Integer, _ Optional ByVal startIndex As Integer = 1) As Variant Const METHOD_NAME As String = "addColumns" '------------------------------------------------------------------------------------------------------ Dim results() As Variant Dim row As Long Dim sourceColumnsCounter As Integer Dim originalColumn As Long Dim destinationColumn As Long '------------------------------------------------------------------------------------------------------ 'Resize the result array to the proper size (it must have as many rows as the original array and ----| 'n more columns, where n is equal to [startIndex] parameter). '| ReDim results(LBound(arr, 1) To UBound(arr, 1) + howManyColumns, LBound(arr, 2) To UBound(arr, 2)) '| '----------------------------------------------------------------------------------------------------| 'Find the proper value of startIndex (it can not excess the total number of columns in the array). --| sourceColumnsCounter = arraySize(arr, 1) '| '| If VBA.Sgn(startIndex) = -1 Then '| '| '--------------------------------------------------------------------------------------------| '| If VBA.Abs(startIndex) > sourceColumnsCounter Then '| '| startIndex = 0 '| '| Else '| '| startIndex = sourceColumnsCounter + startIndex + 1 '| '| End If '| '| '--------------------------------------------------------------------------------------------| '| '| Else '| '| If startIndex > sourceColumnsCounter Then startIndex = sourceColumnsCounter '| '| End If '| '----------------------------------------------------------------------------------------------------| 'Iterate through all the items from the source array and populate the result array with the same ----| 'values. '| For originalColumn = LBound(arr, 1) To UBound(arr, 1) '| '| '--------------------------------------------------------------------------------------------| '| For row = LBound(arr, 2) To UBound(arr, 2) '| '| '| '| destinationColumn = VBA.IIf(originalColumn > startIndex, _ originalColumn + howManyColumns, originalColumn) '| '| Call assign(results(destinationColumn, row), arr(originalColumn, row)) '| '| '| '| Next row '| '| '--------------------------------------------------------------------------------------------| '| '| Next originalColumn '| '----------------------------------------------------------------------------------------------------| addColumns = results '========================================================================================================== ExitPoint: Exit Function '---------------------------------------------------------------------------------------------------------- NotArrayException: 'Error handling for the case if the given parameter [arr] is not an array. GoTo ExitPoint NotDefinedArrayException: 'Error handling for the case if the given parameter [arr] is an array but it has not been 'initialized yet. GoTo ExitPoint DimensionsException: 'Error handling for the case when the number of dimensions of the array passed to this function 'is different than 2 ... GoTo ExitPoint End Function '********************************************************************************************************** ' Name: arraySize ' Author: mielk | 2014-07-15 ' ' Comment: Function returns the size of the specified dimension of the given array. ' ' Parameters: ' arr Array which size is to be returned. ' dimension Dimension for which the size is to be returned. ' This parameter is optional. If it is skipped, the size of first dimension will ' be returned. ' ' ' Returns: ' Long Size of the given array in the specified dimension. ' ' Examples: ' ----------------------------------------------------------------------------------- ' ' ' ' Exceptions: ' NotArrayException Thrown if the given parameter [arr] is not an array. ' NotDefinedArrayException Thrown if the given paremeter [arr] is an array, but it has not been ' initialized yet. ' IndexOutOfBoundException Thrown if the parameter [dimension] exceeds the number of dimensions ' in the given base array [arr]. ' ' ' --- Changes log ----------------------------------------------------------------------------------------- ' 2014-07-15 mielk Method created. '********************************************************************************************************** Public Function arraySize(arr As Variant, Optional dimension As Integer = 1) As Long Const METHOD_NAME As String = "arraySize" '------------------------------------------------------------------------------------------------------ 'Check if the given parameter [arr] is an array and if it has been already initialized. -------------| 'If it is not an array, code is moved to the label NotArrayException. '| 'If it is an array, but has not been initialized yet, code is moved to the label '| 'NotDefinedArrayException. '| If Not VBA.IsArray(arr) Then GoTo NotArrayException '| If Not isDefinedArray(arr) Then GoTo NotDefinedArrayException '| '----------------------------------------------------------------------------------------------------| 'Compare parameter [dimension] with the number of dimensions in the given array [arr]. If it is -----| 'greater than the number of dimensions, IndexOutOfBoundException is thrown. '| If dimension > countDimensions(arr) Then GoTo IndexOutOfBoundException '| '----------------------------------------------------------------------------------------------------| 'Calculate the size of the given array in the given dimension. --------------------------------------| arraySize = UBound(arr, dimension) - LBound(arr, dimension) + 1 '| '----------------------------------------------------------------------------------------------------| '========================================================================================================== ExitPoint: Exit Function '---------------------------------------------------------------------------------------------------------- NotArrayException: 'Error handling for the case if the given parameter [arr] is not an array. GoTo ExitPoint NotDefinedArrayException: 'Error handling for the case if the given parameter [arr] is an array but it has not been 'initialized yet. GoTo ExitPoint IndexOutOfBoundException: 'Error handling for the case if the given dimension exceeds the number of dimensions in the given 'array [arr] GoTo ExitPoint End Function '********************************************************************************************************** ' Name: isDefinedArray ' Author: mielk | 2012-03-27 ' ' Description: Function to check if the given parameter is an array with dimensions and sizes already ' declared. ' ' Parameters: ' arr Parameter to be tested. ' ' Returns: ' Boolean True - if parameter [arr] is an array and its dimensions and sizes has been already ' defined. ' False - if parameter [arr] is not an array or it is declared as a dynamic array but its ' dimension and size have not been defined yet. ' ' --- Changes log ----------------------------------------------------------------------------------------- ' 2012-03-27 mielk Function created. ' 2014-08-10 mielk Case about arrays with negative up bound instead of being not declared. '********************************************************************************************************** Public Function isDefinedArray(arr As Variant) As Boolean Const METHOD_NAME As String = "isDefinedArray" '------------------------------------------------------------------------------------------------------ Dim upBound As Long Dim lowBound As Long '------------------------------------------------------------------------------------------------------ 'Try to assign bottom and top bound of the given parameter. 'If it is not an array or is not declared yet, code will move to 'the label NotArrayException and function will return False. On Error GoTo NotArrayException upBound = UBound(arr, 1) lowBound = LBound(arr, 1) 'In some cases, it is possible to get LBound and UBound of a dynamic array 'althought it is not declared yet (i.e. arrays returned as a result of VBA 'built-in Split function if empty string is passed as a parameter), 'however in this case UBound will be lower than LBound. isDefinedArray = (upBound >= lowBound) '========================================================================================================== ExitPoint: Exit Function '---------------------------------------------------------------------------------------------------------- NotArrayException: GoTo ExitPoint End Function '********************************************************************************************************** ' Name: countDimensions ' Author: mielk | 2012-03-03 ' ' Comment: Returns the number of dimensions of the given VBA array. ' ' Parameters: ' arr Array for which number of dimensions is to be returned. ' ' Returns: ' Integer The number of dimensions of the given VBA array. ' If the given value is not an array function returns -1. ' If the given value is declared as a dynamic array but its dimensions have not been ' declared yet, 0 is returned. ' ' ' --- Changes log ----------------------------------------------------------------------------------------- ' 2012-03-03 mielk Function created. ' 2014-06-15 mielk Returned type changed to Integer to allow -1 to be returned. ' For non-arrays values -1 is returned. '********************************************************************************************************** Public Function countDimensions(arr As Variant) As Integer Const METHOD_NAME As String = "countDimensions" '------------------------------------------------------------------------------------------------------ Dim bound As Long '------------------------------------------------------------------------------------------------------ If VBA.IsArray(arr) Then On Error GoTo NoMoreDimensions Do bound = UBound(arr, countDimensions + 1) countDimensions = countDimensions + 1 Loop Else countDimensions = -1 End If '---------------------------------------------------------------------------------------------------------- NoMoreDimensions: End Function