es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo definir una función DIAG?

Me gustaría definir una función VBA que:

  1. devuelva un vector columna de los elementos de la diagonal principal de una matriz;
  2. devuelva una matriz diagonal cuadrada con los elementos del vector en la diagonal principal;
  3. devuelva automáticamente una matriz/vector, sin necesidad de presionar Ctrl Alt Intro;

Estoy trabajando en este código:

Public Function DIAG(matrix As Variant) As Variant
Dim i As Long
Dim j As Long
Dim nRows As Long
Dim nCols As Long
Dim tempArray As Variant

nRows = matrix.Rows.Count
nCols = matrix.Columns.Count

For i = 1 To nRows
    For j = 1 To nCols
        If i = j Then
           tempArray(i) = matrix(i, j)
        End If
    Next j
Next i

DIAG = tempArray

End Function

que solo sirve para el primer propósito de la función, pero no está funcionando. Obtengo:

VALUE

“`

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Hay algunos problemas con el código proporcionado. En primer lugar, la variable tempArray necesita ser dimensionada como un array antes de poder ser utilizada para almacenar los elementos diagonales. En segundo lugar, si se pasa el argumento de la matriz como un objeto rango, las propiedades Rows y Columns deben ser reemplazadas por las propiedades Rows.Count y Columns.Count respectivamente.

    Aquí hay una versión modificada del código que debería funcionar para el primer propósito:

    Public Function DIAG(matriz As Variant) As Variant
    
    Dim i As Long
    Dim j As Long
    Dim nFilas As Long
    Dim nColumnas As Long
    Dim tempArray() As Variant
    
    nFilas = matriz.Rows.Count
    nColumnas = matriz.Columns.Count
    ReDim tempArray(1 To nFilas)
    
    For i = 1 To nFilas
        For j = 1 To nColumnas
            If i = j Then
               tempArray(i) = matriz(i, j)
            End If
        Next j
    Next i
    
    DIAG = Application.WorksheetFunction.Transpose(tempArray)
    
    End Function
    

    Nótese que ahora la variable tempArray está dimensionada como un array utilizando la instrucción ReDim. Además, la última línea del código utiliza la función Transpose para convertir el array en un vector de columna.

    Para lograr el segundo propósito de la función, el código puede ser modificado de la siguiente manera:

    Public Function DIAG(matriz As Variant) As Variant
    
    Dim i As Long
    Dim j As Long
    Dim nFilas As Long
    Dim nColumnas As Long
    Dim tempArray() As Variant
    Dim matrizDiagonal As Variant
    
    nFilas = matriz.Rows.Count
    nColumnas = matriz.Columns.Count
    ReDim tempArray(1 To nFilas)
    
    For i = 1 To nFilas
        For j = 1 To nColumnas
            If i = j Then
               tempArray(i) = matriz(i, j)
            End If
        Next j
    Next i
    
    ReDim matrizDiagonal(1 To nFilas, 1 To nFilas)
    For i = 1 To nFilas
        matrizDiagonal(i, i) = tempArray(i)
    Next i
    
    DIAG = matrizDiagonal
    
    End Function
    

    Esta versión del código crea un nuevo array, matrizDiagonal, para almacenar la matriz diagonal. La matriz se crea recorriendo cada elemento diagonal en tempArray y asignándolo a la posición correspondiente en matrizDiagonal. Nótese que el array matrizDiagonal también está dimensionado utilizando la instrucción ReDim.

    Finalmente, para lograr el tercer propósito de la función, el código puede ser modificado aún más utilizando el tipo de dato Variant para el argumento de la matriz y utilizando la propiedad Application.Caller para determinar el tamaño de la matriz:

    Public Function DIAG(matriz As Variant) As Variant
    
    Dim i As Long
    Dim j As Long
    Dim nFilas As Long
    Dim nColumnas As Long
    Dim tempArray() As Variant
    Dim matrizDiagonal As Variant
    Dim arrayResultado As Variant
    
    nFilas = Application.Caller.Rows.Count
    nColumnas = Application.Caller.Columns.Count
    ReDim tempArray(1 To nFilas)
    
    For i = 1 To nFilas
        For j = 1 To nColumnas
            If i = j Then
               tempArray(i) = matriz(i, j)
            End If
        Next j
    Next i
    
    ReDim matrizDiagonal(1 To nFilas, 1 To nFilas)
    For i = 1 To nFilas
        matrizDiagonal(i, i) = tempArray(i)
    Next i
    
    If nFilas = nColumnas Then
        arrayResultado = matrizDiagonal
    Else
        arrayResultado = Application.WorksheetFunction.Transpose(tempArray)
    End If
    
    DIAG = arrayResultado
    
    End Function
    

    Esta versión del código utiliza la propiedad Application.Caller para determinar el tamaño de la matriz y lo asigna a las variables nFilas y nColumnas. Si la matriz es cuadrada, la función devuelve la matriz diagonal, de lo contrario devuelve un vector de columna con los elementos diagonales utilizando la función Transpose. El valor de retorno se asigna a la variable arrayResultado, que luego se utiliza como el resultado de la función utilizando la instrucción DIAG = arrayResultado.

Comments are closed.