0

I'm already using the following code to copy a file to Livelink:

Public Function saveFileLL(target As Long, pathSource As String, fileName As String) As Boolean
    Dim dav As New ADODB.Record
    Dim files As New ADODB.Recordset
    Dim objStream As New ADODB.Stream
    Dim url As String

    If Not Val(Nz(target, 0)) > 0 Or Not pathSource Like "*.*" Or Not fileName Like "*.*" Then
        saveFileLL = False
        Exit Function
    End If

    url = URL_LIVELINK_DAV & target

    dav.Open url, , adModeReadWrite
    Set files = dav.GetChildren

    If Not (files.BOF And files.EOF) Then files.MoveFirst

    Do Until files.EOF
        If fileName Like Replace(files("RESOURCE_DISPLAYNAME"), "_", "?") Then Exit Do
        files.MoveNext
    Loop

    If files.EOF Then
        files.addnew "RESOURCE_PARSENAME", fileName
        files.Update
    End If

    files.Close
    dav.Close

    objStream.Open "URL=" & url & "/" & fileName, adModeWrite
    objStream.Type = adTypeBinary
    objStream.LoadFromFile pathSource
    objStream.Flush
    objStream.Close

    Set dav = Nothing
    Set files = Nothing
    Set objStream = Nothing

    saveFileLL = True
End Function

Now, as the title says, I would like to do the same but with a folder. I guess my question isn't really related to Livelink but more to the way to handle folders in general. Is it possible to move a folder with all his children without looping through all the subfolders/files? How could I adapt my saveFileLL() function to do so?

EDIT:

Here is another portion of code that allows me to directly create one folder into the Livelink folder designed by objId.

Public Function CreateFolderToLLFolder(ObjId As String, folderName As String, Optional getId As Boolean = False) As String
    Dim davfile As New ADODB.Record
    Dim davFiles As New ADODB.Recordset
    Dim davDir As New ADODB.Record

    Dim newDirFields(1) As Variant
    Dim newDirValues(1) As Variant

    newDirFields(0) = "RESOURCE_PARSENAME"
    newDirValues(0) = folderName
    newDirFields(1) = "RESOURCE_ISCOLLECTION"
    newDirValues(1) = True

    Set davDir = connection(ObjId, "")
    Set davFiles = davDir.GetChildren()
    If (davFiles.Supports(adAddNew)) Then
        davFiles.addnew newDirFields, newDirValues
    End If

    davfile.Open davFiles, , adModeReadWrite
    CreateFolderToLLFolder = davfile.fields("urn:x-opentext-com:ll:properties:nodeid").value
End Function

Public Function connection(ObjId As String, Optional filename As String = "") As ADODB.Record
    Dim davDir As New ADODB.Record
    davDir.Open filename, "URL=http://livelink-server/livelinkdav/nodes/" & ObjId & "/", adModeReadWrite, adFailIfNotExists, DelayFetchStream, "", ""
    Set connection = davDir
End Function

Don't ask me why this works, I found this and it does work. objId for those wondering is the unique ID that Livelink gives to all his files/folders.

Thank you.

dan
  • 3,439
  • 17
  • 54
  • 82
  • A little bit ya but I can't find a lot of documentation about the Livelink API. I added some details to my original post, I found a clever way to create a folder. It seems quick, I will probably end up looping through my folder to create all the folders/subfolders. – dan Jan 16 '13 at 14:42
  • You can use the tool DMS-Shuttle for LiveLink for these purposes. It can upload / download folder structures with its children to / from LiveLink. There is a trial version: http://dms-shuttle.com/downloads/. For students it is free. Disclaimer: I'm working for the company. – A.Weber Dec 16 '16 at 11:24

2 Answers2

0

You could save a whole set of folder and it's constituent files/subfolders as one block by zipping them and then upload the zip file. Like this http://www.rondebruin.nl/windowsxpzip.htm

If you want to reflect the structure in LiveLink then you'd have to explore the folder tree to replicate content - but there's plenty of vba code around to loop through files & folder trees and it can all call into your saveFileLL function if you have to go that route.

James Snell
  • 604
  • 4
  • 13
  • The problem is that the server pings at ~1500ms. If I need to loop to create ~50 folders, it's 50x1.5s which is a lot of time. And because it's always the same folder structure that I need to copy, I could zip it manually one time. But how do I unzip it once into Livelink? – dan Jan 16 '13 at 13:57
  • The plot thickens! I don't know enough about LL to say if you can extract the zip at the server end. But as the latency seems very high I'd break out the high resolution timers (Win32 API) and see where the holdup is and it might give you some ideas. Otherwise can you map a drive to the LL server, is that any quicker or at least work without blocking the thread? – James Snell Jan 16 '13 at 14:51
  • It's not quicker, but it also works and could help to move a full folder without having to manually program the loop. Indeed, it blocks the thread. I never heard of any kind of multithreading in VBA either :( – dan Jan 16 '13 at 18:29
  • My thinking on the mapping is to create a cache in a temp folder which will be quick in VBA as it'll be in local storage. Then use Shell() to kick off a script outside your app to do the high latency copy process, maybe even using a multithreaded copier like robocopy and because it's not VBA doing that work your vba thread and app are now free to do something else. How does that grab you? – James Snell Jan 16 '13 at 22:58
  • I finally got to talk with someone that really knows how to develop around Livelink (as I've said, almost no ressource at all on the Web, that's odd). Livelink is also a Web service, I could in fact get all my job done doing some call to that Web service. I will now learn how to post some data to the right URL and see what it does. Thanks for your help tho. – dan Jan 17 '13 at 14:22
  • I answered my own question to show up what I finally came with. Hopefully it will help some other people. – dan Jan 17 '13 at 15:45
0

The easiest way to perform what I want is finally to use the web service integrated into Livelink. Because there is really not much information on the Web about the whole Livelink API (that's surprising considering all we can find on Google these days), I'm willing to post here my solution. That's in fact really easy.

All I had to do is to install some add-on to Firefox (I used Fox but others would do the job too) to see the HTTP headers/packets when doing some work in Livelink. Most of the times, operations are done with the POST method. I realized with the Fox plugin that 3 POST are sent, the 2 first returned a 401 error while the 3rd returns the right 200 response and got the action done.

Then, I can deduce that Livelink is a SOAP-service based on a NTLM authentification. It looks like it has been developped in ASP.net.

To use the webservice within VBA, nothing more easy. You will need the Microsoft XML v6.0 livrary for the MSXML2 object, and there you go:

Dim sMsg As String
Dim sURL As String, postData As String
Dim ObjHTTP As Object

Set ObjHTTP = New MSXML2.XMLHTTP
sURL = "http://server.com/livelink/livelink.exe"
postData = "your-post-data"

ObjHTTP.Open "Post", sURL, False
ObjHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
ObjHTTP.send (postData)

Set ObjHTTP = Nothing

As simple as that, just find the right POST data with some kind of browser's plugin and you got it. Most of the post-data isn't encoded and easy to deal with.

dan
  • 3,439
  • 17
  • 54
  • 82