Avatar billede Morten Nybegynder
03. oktober 2003 - 11:05 Der er 45 kommentarer og
2 løsninger

Application.WorksheetFunction.Transpose

Hej

Jeg skal have Transponeret et array - min kode ser ud som følgende:

Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim intColIndex As Integer
Dim DBPath, DBBase, i, j, tmpList As Variant, tmpRSList As Variant
Dim Count1, count2
DBPath = GetName("strPathDB")
DBBase = GetName("strMainDB")


    ' open the database
    Set cn = New ADODB.Connection
    cn.Open "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & _
        DBPath & DBBase & ";"
    Set rs = New ADODB.Recordset
    With rs
        ' open the recordset
        .Open DBTable, cn, adOpenStatic, adLockOptimistic, adCmdTable
        tmpRSList = rs.GetRows
       
        ReDim tmpList(0 To rs.Fields.Count - 1, 0 To rs.RecordCount - 1)
       
tmpList=rs.GetRows

        tmpList = Application.WorksheetFunction.Transpose(tmpList)

    End With
    rs.Close
    Set rs = Nothing
    cn.Close
    Set cn = Nothing

Men den kommer og siger:

Type mismatch på linien tmpList = Application.WorksheetFunction.Transpose(tmpList)

Jeg tror at jeg har fundet fejlen som formenlig består i at posterne i tmpList er i string format og de skal være varianter - men hvordan ændre jeg dette???
Avatar billede Morten Nybegynder
03. oktober 2003 - 11:24 #1
altså når jeg kigger på tmpList i Watches vinduet ser posterne ud som følg.:

tmpList(0)                          Variant(0 to 8)
  tmpList(0,0)    "11111111"        Variant/String
  etc.
Avatar billede bak Forsker
03. oktober 2003 - 11:25 #2
jeg synes at du tager et par omveje, hvorfor gør du det ?
Prøv at skimme nedenstående som jeg bruger til at hente data til en list.

Public Liste()
Public Sub GetTable()

    Dim rsData As ADODB.Recordset
    Dim szConnect As String
    Dim szSQL As String
    Dim Database As String
    Dim Tabel As String
    Database = "o:\logistik\database\logistik.mdb"
    Tabel = "leverandørkart"

    'connection string.
    szConnect = "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" & Database & ";"
   
    'SQL Statement.
    szSQL = "SELECT Navn, Konto " & _
            "FROM " & Tabel & _
            " WHERE Aktiv = True " & _
            "ORDER BY Navn"
   
    'Create the Recorset object and run the query.
    Set rsData = New ADODB.Recordset
    rsData.Open szSQL, szConnect, adOpenForwardOnly, _
                adLockReadOnly, adCmdText
               
    Liste = Application.WorksheetFunction.Transpose(rsData.GetRows)
End Sub
Avatar billede Morten Nybegynder
03. oktober 2003 - 11:28 #3
Okay - det lyder da for nemt - tester lige...
Avatar billede Morten Nybegynder
03. oktober 2003 - 11:32 #4
Den siger stadig mismatch 

Jeg viser lige hele funktionen:

Public Function GetCust(DBTable As String)
'****************************************************************************************
'*          Function created on 1. October 2003 by Morten Frederiksen                                                                                      *
'*          Function changed on
'*
'****************************************************************************************
'*    Værdier der skal bruges til at hente oplysning fra settings arket              *
'****************************************************************************************

Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim intColIndex As Integer
Dim DBPath, DBBase, i, j, k, tmpList As Variant, tmpRSList As Variant
Dim Count1, count2, posten As Variant
DBPath = GetName("strPathDB")
DBBase = GetName("strMainDB")


    ' open the database
    Set cn = New ADODB.Connection
    cn.Open "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & _
        DBPath & DBBase & ";"
    Set rs = New ADODB.Recordset
    With rs
        ' open the recordset
        .Open DBTable, cn, adOpenStatic, adLockOptimistic, adCmdTable


        GetCust = Application.WorksheetFunction.Transpose(rs.GetRows)

    End With
    rs.Close
    Set rs = Nothing
    cn.Close
    Set cn = Nothing

End Function
Avatar billede bak Forsker
03. oktober 2003 - 11:37 #5
prøv lige det her
Public Function GetCust(DBTable As String) as Variant
Avatar billede Morten Nybegynder
03. oktober 2003 - 11:42 #6
Hjalp ikke
Avatar billede Morten Nybegynder
03. oktober 2003 - 12:30 #7
Nu har jeg prøvet at skrive din kode af men nu kommer den med en fejl om at enten EOF eller BOF er nået....... jeg kan se at rsDAta indeholder posterne...

Du får lige koden
Public Function GetCust2(DBTable As String) As Variant

Dim rsData As ADODB.Recordset
Dim szConnect As String
Dim szSQL As String
Dim Database As String

Database = GetName("strPathDB") & GetName("strMainDB")

'connection string
szConnect = "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" & Database & ";"

'SQL statement.
szSQL = "SELECT * " & _
      "FROM " & DBTable

'Create the Recordset object and run the query
Set rsData = New ADODB.Recordset
rsData.Open szSQL, szConnect, adOpenForwardOnly, adLockReadOnly, adCmdText

GetCust2 = Application.WorksheetFunction.Transpose(rsData.GetRows)

End Function

Og den fejler altså på GetCust2=.....
Avatar billede Morten Nybegynder
03. oktober 2003 - 12:34 #8
Fejlen er helt præcis:

Run-time error '3201':

Enten er BOF eller EOF sand, eller den aktuelle post er blevet slettet.
Den anmodede handling kræver en aktuel post.
Avatar billede Morten Nybegynder
03. oktober 2003 - 12:40 #9
og det er fordi EOF = true når jeg kigger på rsData...??????????
Avatar billede Morten Nybegynder
03. oktober 2003 - 12:43 #10
Nu har jeg ændre:
rsData.Open szSQL, szConnect, adOpenForwardOnly, adLockReadOnly, adCmdText
til
rsData.Open szSQL, szConnect, adOpenStatic, adLockOptimistic, adCmdText

Og nu når jeg videre til Transpose men får så samme fejl at det er mismatch?

Jeg fatter ikke en meter af det her...????
Avatar billede Morten Nybegynder
03. oktober 2003 - 12:46 #11
Hmmmmm

Var desperat - så gik i database og udfyldte de tomme felter (ikke alle kunder har udfyldt alle felter) og nu virker den... hmmmmmmmmmm....

Men vil det sige at jeg ikke kan transponerer hvis nogle felter indeholder Null-værdier????????????????????????????????????????
Avatar billede bak Forsker
03. oktober 2003 - 13:00 #12
jeg tror jeg ved hvorfor den fejler.
rs felterne starter ved 0, dvs rs(0) er første felt.
Transpose kan ikke klare at starte ved 0.
Det er lidt ligesom  Option base 1.
hvis du istedet definerer i szSql hvilke felter du vil have overført går det fint.

szSQL = "SELECT Navn, Konto FROM " & DBTable
Avatar billede Morten Nybegynder
03. oktober 2003 - 13:05 #13
Nej det tror jeg altså ikke - det er fordi nogle af posterne indeholder værdien Null (eller det er jo ikke en værdi nærmere ingenting) - når jeg går i databasen og indsætter et X i de tomme felter så virker skidtet...

Og jeg ville også være ked af at skulle indsætte felter for så kan jeg ikke bruge funktionen til andre tabeller - det var jo tanken at den skulle kunne bruges til mange andre funktioner også... ;O)

Men ved du om der er en løsning på Null problemet - jeg kan selvfølelig definere at tabellen ikke må indeholde Null - men det synes jeg ikke om - da f.eks. ikke alle har en e-mail osv. osv.
Avatar billede Morten Nybegynder
03. oktober 2003 - 13:18 #14
Jeg mangler ikke nogle referencer eller noget?

Hvilke referencer bør man have????
03. oktober 2003 - 15:11 #15
Prøv lige om dette gøre en forskel
tmpList = Application.WorksheetFunction.Transpose(CVar(tmpList))
03. oktober 2003 - 15:11 #16
eller dette
tmpList=CVar(rs.GetRows)
Avatar billede Morten Nybegynder
03. oktober 2003 - 15:16 #17
Det hjælper ikke - har jeg prøvet

Altså som tingene står nu så ser min kode ud som følgende:

Public Function GetCust(DBTable As String) As Variant
  Dim rsData As ADODB.Recordset, szConnect As String, szSQL As String, Database As String
 
    Database = GetName("strPathDB") & GetName("strMainDB")
   
    'connection string
    szConnect = "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" & Database & ";"
   
    'SQL statement.
    szSQL = "SELECT * " & _
          "FROM " & DBTable
   
    'Create the Recordset object and run the query
    Set rsData = New ADODB.Recordset
    rsData.Open szSQL, szConnect, adOpenStatic, adLockOptimistic, adCmdText
   
    GetCust = Application.WorksheetFunction.Transpose(rsData.GetRows)
    rsData.Close
    Set rsData = Nothing

End Function

Og den virker perfekt så længe alle poster i min DB ikke indeholder Null-værdier...

Men det er irreterende at alle felter skal være udfyldt - så hvis du har en løsning på dette...?

Tænkte lige om det er muligt at trasnponerer i ren VB(A) ???

Altså en funktion som ikke er en worksheetfunction?
03. oktober 2003 - 15:22 #18
Det kan vel gøres med en For..Next løkke der løber et array igennem, og samtidig udvider det andet.
Avatar billede Morten Nybegynder
03. oktober 2003 - 15:30 #19
Okay - det havde jeg også tænkt på - men ville lige høre om der fandtes en funktion som kunne.... så'n automatisk...

Men den med Null-værdier har du ingen løsning på eller?
03. oktober 2003 - 15:35 #20
Brug funktionen IsNull() til at validere dine data
Hvis IsNull() = false så brug dine data ellers brug f.eks. = ""
en tom string er nemlig ikke Null
03. oktober 2003 - 15:37 #21
hvis dine data nu hedder DATA, så kan du gøre sådan her med dem alle
DATA = "" & DATA
så bliver Null værdier erstattet med en tom string og resten sker der ikke noget med
Avatar billede Morten Nybegynder
03. oktober 2003 - 15:38 #22
Hmmmmm... ja - og ellers må jeg jo lave min egen Transponerings-funktion...

Det tror jeg lige jeg vil lege lidt med og så poste den her...

Kunne I ikke begge smide et svar så I kan få point få ulejligheden

...og så venligst tag et kig på spørgsmål http://www.eksperten.dk/spm/409090
for det er godt nok noget L.....

Tak for hjælpen
Avatar billede Morten Nybegynder
03. oktober 2003 - 15:39 #23
Din Data funktion hmmm... så skal jeg jo gennemløbe alle posterne - ajjj jeg tror at det bedste er at jeg laver en transponerings funktion...
03. oktober 2003 - 15:44 #24
I din transporeringsfunktion håndterer du IsNull() med den tomme string "", hvis du kommer i problemer der.
Avatar billede Morten Nybegynder
03. oktober 2003 - 15:48 #25
Okay.. du får point når Bak har svaret....
Avatar billede Morten Nybegynder
03. oktober 2003 - 15:58 #26
>> Flemming et lille tillægsspørgsmål

Hvis nu jeg skal lave en funktion som istedet for at hente skal skrive - hvor skal jeg så rette?

Altså jeg ved godt at jeg skal bruge insert into... men skal jeg rette i den måde jeg åbner ???

Findes der ikke noget hjælp - jeg kan ikke finde noget ADO hjælp i Excel - måske mangler jeg igen en reference ????????? Eller findes der nogle Web-steder for Dummies som mig???
Avatar billede bak Forsker
03. oktober 2003 - 16:23 #27
jeg tror heller ikke du kommer uden om problemet, uden at lave din egen transponeringsfunktion. Nu har jeg også prøvet at teste med null-værdier.
Hvad med at indsætte et mellemrumstegn i databasen, når når et felt ikke udfyldes ? Du vil jo styre indsættelsen gennem excel-form, så det skulle vel ikke være et problem.
03. oktober 2003 - 16:26 #28
det er kun sql-sætningen der skal være anderledes - åben og luk af database er det samme
Avatar billede Morten Nybegynder
03. oktober 2003 - 16:27 #29
Det er også en løsning jeg har tænkt på - men virker det ikke "Rigtigst" hvis jeg laver den funktion?

Iøvrigt kunne den jo være vældig brugbar senere også..... så det bliver nok den
Avatar billede Morten Nybegynder
03. oktober 2003 - 16:30 #31
Mht. til sql - ja det fandt jeg ud af men den brokker sig over min sætning og jeg kan ve en eller anden ikke se hvad jeg gør forkert - jeg er nu igang med at indsætte elementerne et ad gang for at se hvor fejlen er men måske du kan se det med det vups?:

INSERT INTO Kundebase(Kundenr, Navn. Adresse, Postnr, By, KontaktPerson, Email, Telefon, Fax, Mobiltelefon, Oplysninger) VALUES('Test1','Test2','Test3','4300','Holbæk','Test4','test5','test6','test7','test8','test9');
Avatar billede Morten Nybegynder
03. oktober 2003 - 16:31 #32
Måske punktumet efter navn hahah
03. oktober 2003 - 16:32 #33
tjaaa............ måske et eller flere af disse felter - Postnr, Telefon, Fax, Mobiltelefon - tal skal ikke have de små ' ' omkring sig......... check felt defineringer i din database....
Avatar billede Morten Nybegynder
03. oktober 2003 - 16:34 #34
Nope den brokker sig stadig:

INSERT INTO Kundebase(Kundenr, Navn, Adresse, Postnr, By, KontaktPerson, Email, Telefon, Fax, Mobiltelefon, Oplysninger) VALUES('TEST25','TEST26','TEST26','2770','Kastrup','TEST26','TEST26','TEST26','TEST26','TEST26','TEST26');
Avatar billede Morten Nybegynder
03. oktober 2003 - 16:35 #35
De er alle tekstfelter...
03. oktober 2003 - 16:35 #36
2770  ikke '2770' ....... sådan som jeg lige husker det
Avatar billede Morten Nybegynder
03. oktober 2003 - 16:37 #37
Lige et allersidste spørgsmål..:

I forbindelse med projekt Transponering kan jeg hive arrayets størrelse ud ?

Altså hvis jeg har et array der hedder Data om som er dimmet således Data(1 to 10, 1 to 20) kan jeg så hente 10 og 20???
Avatar billede Morten Nybegynder
03. oktober 2003 - 16:37 #38
Men det er et tekstfelt i databasen?
Avatar billede bak Forsker
03. oktober 2003 - 16:39 #39
Ny transpose funktion. Læs iøvrigt http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/q246/3/35.asp&NoWebContent=1 , specielt denne del:

If you decide to use Excel's Transpose method instead of the TransposeDim() function to transpose the array, you should be aware of the following limitations with the Transpose method:
The array cannot contain an element that is greater than 255 characters.
The array cannot contain Null values.
The number of elements in the array cannot exceed 5461.
If the above limitations are not taken into consideration when you copy an array to an Excel worksheet, one of the following run-time errors may occur:

Run-time Error 13: Type Mismatch
Run-time Error 5: Invalid procedure call or argument
Run-time Error 1004: Application defined or object defined error


Function TransposeDim(v As Variant) As Variant
' Custom Function to Transpose a 0-based array (v)
   
    Dim X As Long, Y As Long, Xupper As Long, Yupper As Long
    Dim tempArray As Variant
   
    Xupper = UBound(v, 2)
    Yupper = UBound(v, 1)
   
    ReDim tempArray(Xupper, Yupper)
    For X = 0 To Xupper
        For Y = 0 To Yupper
            tempArray(X, Y) = v(Y, X)
        Next Y
    Next X
   
    TransposeDim = tempArray

End Function
03. oktober 2003 - 16:40 #40
Kan ikke lige se hvad der er galt i din INSERT LINIE........


Hente array størrelser
10 fåes ved  UBound(Data,1)
20 fåes ved  UBound(Data,2)
fangede du den logik ?
Avatar billede Morten Nybegynder
03. oktober 2003 - 16:41 #41
Ha - der sparede du mig nok for en del arbejde hahahaa

Fedest...
Avatar billede Morten Nybegynder
03. oktober 2003 - 16:42 #42
jeps - er vist ved at være træt - det var for logisk - hmmm
Avatar billede Morten Nybegynder
03. oktober 2003 - 16:56 #43
Okay... mht. SQL det er åbenbart fordi jeg bruger By.... den skal sættes i []

Hmmmmmmmm..... jeg lærer det nok en dag hahahaha
Avatar billede bak Forsker
03. oktober 2003 - 17:07 #44
Ja, det virker måske ikke helt logisk, men jeg gætter på BY er et reserveret ord i SQL  (fx. Order By)
Avatar billede Morten Nybegynder
03. oktober 2003 - 17:10 #45
jeps
03. oktober 2003 - 18:45 #46
hehe - nogle gange er "fejlene" bare for simple *gg*
Avatar billede Morten Nybegynder
05. oktober 2003 - 23:13 #47
OBS - Den Transpose funktion virker rigtig godt...!!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Excel kurser for alle niveauer og behov – find det kursus, der passer til dig

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester