XL 2013 connaitre le type de variable tableau un ou 2 dim et le sens

patricktoulon

XLDnaute Barbatruc
Bonjour a tous
je cherche un moyen efficace de savoir quelle est le type de variable tableau une ou deux dim et est une ligne ou une colonne sans avoir a gérer des erreurs dans un sens ou dans l'autre
@Yeahou a donné un début de piste interessant mais c'est pas full right

VB:
Sub testy7()
a = [A1:H1].Value
MsgBox oneDim(a)
End Sub

Sub testy8()
a = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
MsgBox oneDim(a)
End Sub

Sub testy9()
Dim a(0 To 5, 1)
  a(5, 0) = "toto "
MsgBox oneDim(a) & " " & UBound(a, 2)
End Sub

'***********************************************************
'ERREUR!!!!
Sub testy10() ' erreur donne vrai quand base 0
Dim a(0 To 5, 0)
  a(5, 0) = "toto "
 'a(5) = "titi"    'erreur " nombre de dimensions incorect"
Msgbox  oneDim(a) & " " & UBound(a, 2)
End Sub
'***********************************************************

Sub testy11() '
Dim a(0 To 5)
MsgBox oneDim(a)
End Sub

Function oneDim(a)
  oneDim = UBound(a) + 1 - LBound(a) = Application.CountA(a)
End Function

il faudrait le moyen de compter le base 0 et ce sera bon
 
Solution
re
Bonjour @Yeahou
oui perso moi aussi je l'utilise rarement le ".iserr" de l'app
j'utilise typename par ce que je fait la même chose avec evaluate

pour le coup là il y en a pour tout les goûts

3 écriture différentes

sub de test

VB:
Dim q(1 To 1000000, 1 To 1)

Sub test0()    'tableau 1 colonne explicite base(1,1)
    MsgBox GetTypeArray(q)
    MsgBox GetTypeArray2(q)
    MsgBox GetTypeArray3(q)
End Sub

Sub testX0()    'tableau 1 colonne explicite base(1,1)
    Dim t
    t = [A1].Resize(1000000, 1).Value
    MsgBox GetTypeArray(t)
    MsgBox GetTypeArray2(t)
    MsgBox GetTypeArray3(t)
End Sub

Sub test1()    'tableau 1 colonne explicite base (1,1)
    t = [A1:A1000000].Value
    MsgBox...

patricktoulon

XLDnaute Barbatruc
j'aurais bien une autre idée pour me simplifier la tache
mais je n'ai pas poussé ma réfection encore sur ce principe
j'e n'aurais plus a déterminer le type ou dimensions

l'astuce serait plutôt que de boucler for i = x to y

je bouclerais for each element in tablo
reste qu'il me faut déterminer le précédent et le suivant
sauf que element renvoie la valeur de l'item pas l'index
peut être avec une incrémentation numérique synchro je sais pas

@job75 j'aime bien me triturer les neurones ( c'est bon pour rester en forme et alerte )
;)
 

Dranreb

XLDnaute Barbatruc
J'ai quelque part un vieux module FaciliteurExcelVBA qui fait ce genre de choses.
Il contient notamment :
VB:
Property Get TableÀRendre(Table() As Double) As Variant
Dim RgAC As Range, N As Long
Dim OrientésTousDeux As Boolean, TbVertical As Boolean, RgVertical As Boolean
On Error Resume Next
TbVertical = UBound(Table, 2) = LBound(Table, 2)
If Err Then
   OrientésTousDeux = UBound(Table, 1) > LBound(Table, 1)
   TbVertical = False
Else
   OrientésTousDeux = UBound(Table, 1) = LBound(Table, 1) Xor TbVertical
   End If
On Error GoTo 0
If TypeName(Application.Caller) = "Range" Then
   Set RgAC = Application.Caller
     RgVertical = RgAC.Columns.Count = 1
   If RgVertical Eqv RgAC.Rows.Count = 1 Then OrientésTousDeux = False
Else
   OrientésTousDeux = False
   End If
If OrientésTousDeux And (RgVertical Xor TbVertical) Then
   TableÀRendre = WorksheetFunction.Transpose(Table)
Else
   TableÀRendre = Table
   End If
End Property
'

Property Let TableÀRendre(Table() As Double, ByVal V As Variant)
Dim Rg As Range, LMax As Long, CMax As Long, L As Long, C As Long, dL As Long, dC As Long
If TypeName(V) = "Range" Then
   Set Rg = V: V = Rg.Value
   LMax = Rg.Rows.Count: CMax = Rg.Columns.Count
   While WorksheetFunction.IsNA(V(LMax, 1)) And LMax > 1: LMax = LMax - 1: Wend
   While WorksheetFunction.IsNA(V(1, CMax)) And CMax > 1: CMax = CMax - 1: Wend
   V = Rg.Resize(LMax, CMax).Value
   End If
On Error Resume Next
dL = 1 - LBound(V, 1): LMax = UBound(V, 1) + dL
If Err Then dL = 0: LMax = 0
dC = 1 - LBound(V, 2): CMax = UBound(V, 2) + dC
If Err Then dC = 0: CMax = 0: Err.Clear
If LMax > 1 Then
   If CMax > 1 Then
      ReDim Table(1 To LMax, 1 To CMax) As Double
      For L = 1 To LMax: For C = 1 To CMax: Table(L, C) = V(L - dL, C - dC): Next C: Next L
   ElseIf CMax = 1 Then
      ReDim Table(1 To LMax) As Double: C = 1 - dC
      For L = 1 To LMax: Table(L) = V(L - dL, C): Next L
   Else
      ReDim Table(1 To LMax) As Double
      For L = 1 To LMax: Table(L) = V(L - dL): Next L
      End If
ElseIf LMax = 1 Then: L = 1 - dL
   If CMax > 1 Then
      ReDim Table(1 To CMax) As Double
      For C = 1 To CMax: Table(C) = V(L, C - dC): Next C
   ElseIf CMax = 1 Then: C = 1 - dC
      ReDim Table(1 To 1) As Double: Table(1) = V(L, C)
   Else
      ReDim Table(1 To 1) As Double: Table(1) = V(L)
      End If
Else
   ReDim Table(1 To 1) As Double: Table(1) = V
   End If
End Property
Il sert surtout à communiquer avec des dispositifs de résolution de systèmes d'équations en tout genre
 

patricktoulon

XLDnaute Barbatruc
Si tu regardes mon poste #29 tu vois que i est égal à la somme des ubound c'est une piste !
Bonjour robert ;)
oui je l'ai vu
mais ça se complique en base 0/1 (ligne/colonne) et ca n'apporte rien quand au model d'array (array/ligne/colonne)
je peux seulement déterminer (array/tableau ) et encore

mes questions n'ont jamais une réponse simple tu le sais mieux que les autres 🤣🤣🤣

et pour ta dernière j'ai une erreur de syntaxe
1623750583362.png
 

patricktoulon

XLDnaute Barbatruc
re
@Dranreb
il y a des lignes intéressantes dans ton truc
mais a ce que je vois là aussi la gestion d'erreur est manifestement incontournable
ca c'est pâs mal du tout
VB:
On Error Resume Next
TbVertical = UBound(Table, 2) = LBound(Table, 2)
If Err Then
   OrientésTousDeux = UBound(Table, 1) > LBound(Table, 1)
   TbVertical = False
Else
   OrientésTousDeux = UBound(Table, 1) = LBound(Table, 1) Xor TbVertical
   End If
On Error GoTo 0
 

patricktoulon

XLDnaute Barbatruc
S'il n'y a qu'une "ligne" (ou une "colonne"), logiquement ça fait un tableau à une seule dimension
Bonjour @Marcel32
désolé mais tu a tout faux!!!!!!!
exemple
[A1:A10] .value donc une colonne sur 10 lignes = variable tableaux a 2 dimensions

soit l’équivalent en terme de dimension c'est la même chose que

dim tableau( 1 to 10 , 1 to 1)' en base 1
ou !!!
dim tableau( 9 , 1)' en base 0
ou !!!
dim tableau( 9 , 0)' en base 0

on a donc bien deux dimensions

ci dessous là oui on a une seule dimension
dim tableau(1 to 5)' en base 1 (5 items)
dim tableau( 4)' en base 0 (5 item)
application.transpose(application.index([A1:A10].value,0,1)) 'en base 1 (10 items)
application.index([A1:J1].value,1,0)) 'en base 1 (10 items)
 

TooFatBoy

XLDnaute Barbatruc
re
msgbox typename([A1:A10].value)
Je ne sais pas ce que ça doit afficher. 😕

Je croyais, quand tu parlais de "une ligne" (ou "une colonne"), que tu parlais d'une variable de type tableau (utilisée dans ton code), rt donc logiquement à une seule dimension.
C'est pour ça que je faisais remarquer que dans ce cas un tableau n'a pas à proprement parler une "ligne" ou une "colonne", mais simplement une dimension.

Voilà voilà
Bye
 

patricktoulon

XLDnaute Barbatruc
re
ça doit afficher "Variant()"
et
msgbox ubound([A1:A10].value,2)
doit t'afficher "1" si c'est deux dimensions ou message d'erreur si une dimension
quand je parle de ligne ou colonne c'est une vue de l'esprit ( et quoi que ) tout le monde a bien compris
 

dysorthographie

XLDnaute Accro
Bonsoir,
voila un truc que j'ai réalisé en VB.net!
VB:
Imports System.Reflection
Public Class RD
    Public Function MyType(ByVal T As Object) As Object
        Try
            Dim vReturn As String = ""
            Select Case $"{TypeName(T).ToString}(".Split("(")(0)
                Case "Range" : vReturn = TypeName(T).ToString + $"(""{T.address.replace("$", "")}"")"
                Case "Integer", "String", "Object"
                    With TypeName(T).ToString
                        If .IndexOf("(") > 0 Then
                            For i As Integer = 1 To TypeName(T).ToString.Split(",").Count
                                If vReturn <> "" Then vReturn += ","
                                vReturn += UBound(T, i).ToString
                            Next
                            vReturn = $"{TypeName(T).ToString}(".Split("(")(0) + $"({vReturn})"
                        Else
                            vReturn = TypeName(T).ToString
                        End If
                    End With
                Case Else : vReturn = TypeName(T).ToString
            End Select
            Return vReturn
        Catch ex As Exception
            Return ex.Message.ToString
        End Try
    End Function
End Class
1623868670511.png
 

Pièces jointes

  • RD.zip
    10.5 KB · Affichages: 11
Dernière édition:

Discussions similaires

Réponses
7
Affichages
377

Membres actuellement en ligne

Statistiques des forums

Discussions
312 370
Messages
2 087 693
Membres
103 641
dernier inscrit
anouarkecita2