Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

help with substring() 2

Status
Not open for further replies.

Jerim65

Technical User
Aug 8, 2010
99
AU


In my app I have identified a UNC path such as
\\NASSERVER209\MYUSERDATA\EXHIBITS\COLDAN\GENIW0015.JPG from a 3rd party app I work with.

I have created a table of local drives which identifies mapped drives such as

Drive T: is a network drive connected to \\NASSERVER209\MYUserData

I intend to use a LOCATE on that table

On the PC I need 2 GENERAL substr() statements where I can get to the mapped drive label \\NASSERVER209\MYUSERDATA\ from \\NASSERVER209\MYUSERDATA\EXHIBITS\COLDAN\GENIW0015.JPG

The format will always be the same but the length of the subdirs will vary so I'm looking to get everything up to and including the second backslash.

I will then concatenate the drive letter ( T:) to the second substring justpath(\EXHIBITS\COLDAN\GENIW0015.JPG)
from which I can get a list of all files in that folder as described in thread184-1623660

Hopefully someone can help.

Coldan
 
"I'm looking to get everything up to and including the second backslash."

Lets start out by just separating the Path from the File name:
Code:
cPathedFile = "\\NASSERVER209\MYUSERDATA\EXHIBITS\COLDAN\GENIW0015.JPG"
cPath = JUSTPATH(cPathedFile)

Now if you want to get just a part of the Path (the part to the left of and inclusive of the 2nd backslash)

NOTE - what you describe as the 2nd backslash above is really the 4th backslash
Code:
cPartialPath = LEFT(cPath,AT("\",cPath,4))

You can now combine the commands to get:
Code:
cPartialPath = LEFT(JUSTPATH(cPathedFile),AT("\",JUSTPATH(cPathedFile),4))

That should get you what you describe above.

Good Luck,
JRB-Bldr
 
As I see it that's very close..

I can LOCATE with cPartialPath = UPPER(LEFT(cPath,AT("\",cPath,4)))

I get T:

What I actually want is say

T:\MYUSERDATA\EXHIBITS\COLDAN\

using LEFT(JUSTPATH(cPathedFile),AT("\",JUSTPATH(cPathedFile),4))

gives me

T:\\NASSERVER209\MYUserData

Tks

Coldan

 
Using the above, my solution is

nOrigpathlen = LEN(cPartialPath)

cPath2 = SUBSTR(cPathedFile,nOrigpathlen,LEN(cPath )

Coldan
 
You know

lcDrive = "T:"
lcShare = "\\NASSERVER209\MYUserData"

Then you want to replace \\NASSERVER209\MYUserData with T:

Why are you making things so overcomplicated, simply do it:

lcFile = "\\NASSERVER209\MYUSERDATA\EXHIBITS\COLDAN\GENIW0015.JPG"
lcDrivepath = Strtran(upper(lcFile), upper(lcShare), lcDrive)

? lcDrivepath

You can also do the inverse and change all paths beginning with T: to unc paths, no matter wich way you replace, you have then all paths in one way of nomenclature and can compare them.

Bye, Olaf.
 
Olaf,

I don't believe your suggestion takes into account the fact that the UNC path will vary for each user and I need to extract the variable part each time.

Regards

Coldan

 
Code:
Local lcPath, lcLocalPath
lcPath = '\\NASSERVER209\MYUSERDATA\EXHIBITS\COLDAN\GENIW0015.JPG'

GetMappedDrives('MappedDrives')

Local Array laMapInfo[1]
Select MapDrive, MapPath ;
  FROM MappedDrives ;
  WHERE Lower(m.lcPath) Like Lower(MapPath)+'%' ;
  INTO Array laMapInfo

If (_Tally > 0)
  lcLocalPath = Strtran(m.lcPath, Addbs(laMapInfo[2]),Addbs(laMapInfo[1]),1,1,1)
  ? m.lcLocalPath
Endif

Procedure GetMappedDrives(tcCursorName)
  tcCursorName = Evl(m.tcCursorName, 'MapInfo')
  Declare Integer GetDriveType In WIN32API String cDrvLetter
  Declare Integer GetLogicalDriveStrings In Win32API ;
    integer  nBufferLength,	String @ lpBuffer
  Declare Integer WNetGetConnection In win32API ;
    string @ lpLocalName, ;
    string @ lpRemoteName,  ;
    integer @ lpnLength

  Local lpBuffer,nBufferLength,lnBuflen, lpLocalName, lpRemoteName, lpnLength
  Local Array aDriveLetters[1]
  lpBuffer = Space(26*128)
  nBufferLength = 26*128
  lnBuflen = GetLogicalDriveStrings(m.nBufferLength, @lpBuffer)
  Create Cursor (m.tcCursorName) (MapDrive c(2), MapPath m)
  If m.lnBuflen # 0 && Succeeded
    For ix = 1 To Alines(aDriveLetters, m.lpBuffer,1+4+8,Chr(0))
      If (GetDriveType(aDriveLetters[m.ix])=4)
        lpRemoteName = Space(512)
        lpnLength = 512
        lpLocalName = Left(aDriveLetters[m.ix],2)
        If WNetGetConnection(m.lpLocalName, @lpRemoteName, @lpnLength)=0
          Insert Into (m.tcCursorName) Values (m.lpLocalName, ;
            Substr(lpRemoteName, 1, At(Chr(0),m.lpRemoteName)-1))
        Endif
      Endif
    Endfor
  Endif

Cetin Basoz
MS Foxpro MVP, MCP
 
Jeremi65,

I already warned, that drive letters may be mapped different at different computers, but for a given mapping this simply transforms mapped to unc or vice versa.

Cetin has made it more complete, I just gave a partial solution, but it doesn't matter what length the share has, strtran does replace, Cetin used it in his code, too.

Bye, Olaf.
 
Why not use a subroutine that does the following

parameter thestring
x1=thestring
x2=""
y=0
for x3=1 to x1
if y<3
x2=x2+substr(x1,x3,1)
if substr(x1,x3,1)="/"
y=y+1
endif
if y=3
exitfor
endif
next
thestring=x2
return thestring
 
Olaf and Cetin,

We seem to be talking at cross purposes...

The part I need is not from a test for mapped drives.

I simply have a path from another app that I need to 'assemble' into what it would be on a mapped path

ie \\NASSERVER209\MYUSERDATA\EXHIBITS\COLDAN\GENIW0015.JPG'


(I get T: from my lookup of Drive types)

into T:\EXHIBITS\COLDAN\GENIW0015.JPG'

so I need to remove \\NASSERVER209\MYUSERDATA from the original... and this is where this part will vary form user to user.

Thanks

Coldan
 
You can use the basics of what I suggested above....
Code:
cPathedFile = '\\NASSERVER209\MYUSERDATA\EXHIBITS\COLDAN\GENIW0015.JPG'

* --- Get Right of Pathed File from 4th backslash ---
cPartialPathedFile = SUBSTR(cPathedFile,AT("\",cPathedFile,4)+1)

* --- Add New Mapped Drive to Value ---
cNewPathedFile = ADDBS('T:') + cPartialPathedFile

OR if you just want to work with the path itself...

Code:
cPathedFile = '\\NASSERVER209\MYUSERDATA\EXHIBITS\COLDAN\GENIW0015.JPG'

* --- Separate out parts ---
cFileName = JUSTFNAME(cPathedFile)
cOrigPath = JUSTPATH(cPathedFile)

* --- Modify Path ---
cRightPartOfPath = SUBSTR(cOrigPath,AT('\',cOrigPath,4)+1)

* --- Add In New Path Root ---
cNewPath = ADDBS('T:') + cRightPartOfPath

* --- Add Back In File Name ---
cNewPathedFile = ADDBS(cNewPath) + cFileName

Obviously in both cases you can simplify things by combining some of the multiple commands into a single command.

And you can put the whole thing into a loop of some sort if you needed to do this multiple times on multiple Original Pathed Filenames.

Good Luck,
JRB-Bldr

 
And here's yet another approach...
Code:
cOrigPathedFile = '\\NASSERVER209\MYUSERDATA\EXHIBITS\COLDAN\GENIW0015.JPG'

* --- Get Part of Path to Be Removed ---
cToBeRemoved = LEFT(cOrigPathedFile,AT("\",ccOrigPathedFile,4)-1)

* --- Somehow define the Replacement Portion ---
cToReplace = "T:"

* --- Replace Old with New ---
cNewPathedFile = STRTRAN(cOrigPathedFile,cToBeRemoved,cToReplace)

* --- Examine Results (for Development/Debugging Only) ---
?cNewPathedFile

As you can see, there are a variety of ways to approach what you need.

Good Luck,
JRB-Bldr
 
Coldan,
As I understand you don't understand the code.
That code does exactly what you ask for. You are saying that you would use 'T:\' for '\\NASSERVER209\MYUSERDATA\' and that code instead of using such hard coded values querying for the UNC mapping.

Although it is not the proper way to do it, if you are insisting that everytime 'T:\' would stand for '\\NASSERVER209\MYUSERDATA\' then all you need is a simple strtran:

Code:
lcUNCPath = '\\NASSERVER209\MYUSERDATA\EXHIBITS\COLDAN\GENIW0015.JPG'
lcDriveLetter = 'T:\'
lcShareRoot = '\\NASSERVER209\MYUSERDATA\'

lcPath = strtran(m.lcUNCPath, m.lcShareRoot, ;
                 m.lcDriveLetter, 1,1,1)

Cetin Basoz
MS Foxpro MVP, MCP
 
If you meant 'T:' is constant at all times and share root might have changed then still the code I provided applies. Simply change the SQL:

Code:
Local Array laMapInfo[1]
Select MapDrive, MapPath ;
  FROM MappedDrives ;
  WHERE MapDrive = 'T:' ;
  INTO Array laMapInfo

Cetin Basoz
MS Foxpro MVP, MCP
 
If the drive mapping were to possibly change from user to user within the same organization, I would create a Reference Table - something like:

CREATE TABLE "C:\Temp\Drive Mapping.dbf" FREE;
(UNC C(40),;
Mapped C(3),;
User C(30))

Then when I needed to determine a mapping association between a UNC and a particular mapped drive for a given user, I could initially attempt to just look it up.

If I found the particular UNC for that user, then I could get its mapped Drive letter replacement quickly.

If I did not find it, I could go through the more lengthy process of determining it from the Windows Registry, or whatever and then save it in a new reference table record for next time.

Good Luck,
JRB-Bldr
 
Well, Cetin gave you the code to find all mapped drives, so ingeneral you scan over all mapped paths and see if one mathces and then do the replace with the drive letter. The main ingredient still is the STRTRAN() function which replaces the one with the other.

Bye, Olaf.
 
The reason I suggested a subroutine is because this will let you take any string and manipulate it.

For instance I have to turn phone numbers into a standard format. I can not control the input which comes from a separate web programs.

I might get (702)999-9999 or 702-999-9999 or 702-9999999#45 or 702 999 9999 or 702.999.9999 or 1-702-999-9999

What I need is 7029999999.

using the lop lets me do that. I can also send the area code to one field and the main number to another. I can even strip the 1. Phone numbers never start with a 1. Likewise I never want extentions so I can strip them. If I did want them theyed go to a different field and this would let me grab them.

 
Reread now, but I may still not getting your problem.

My understanding is that you have two lists of file names and want to compare/find matches.

Then it doesn't matter, if you replace unc parts with drive letter or vice, it only matters to get all paths into one format, and the unc path is the more universal format of a path, as it will be independant on drive mappings.

Maybe you explain your problem a little more general instead of diving into details, you might get a better answer.

Bye, Olaf.
 
Thanks Everybody.

I have enough information now to get what I need in my app.

Regards

Coldan
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top