Tuesday, September 30, 2008

Annoying Visual Studio Behavior (Auto format stops working)

Of late I have had this annoying thing happen to my Visual Studio 2005 environment where it stops formatting my code for me. So would call me lazy… J I am… I had tried resetting the environment to be a Visual Basic Env etc… etc… nothing worked.

 

To fix it I found a link to an MSDN forum:

 

http://social.msdn.microsoft.com/Forums/en-US/csharpide/thread/870c32f4-464b-4701-986a-290fc996a570/

 

 

Short Version:

Reset the environment completely…

 

AdamPe States:

“You need the /resetuserdata Switch

1.       Shut down all instances of Visual Studio 2005.

2.       Click Start, the choose Run....

3.       Type "devenv.exe /resetuserdata".

Easy when you know how!!”

More details here:
http://msdn2.microsoft.com/en-us/library/bb245788(vs.80).aspx

 

Tuesday, September 23, 2008

Frustrating CI Issue PSBusComp error

I've been having an issue when connecting to a CI (peopleTools 8.49.11) in that as I start working with a component and iterating through data to dump in, there seems to be a point where the OS kills the process that I am using.

Here is what I am doing:

Pulling the rows to insert directly from the DB
Connecting to a CI via JSL to the App server
Start the Loop to pump the data in
The first rows go in well
The the App server kills the run after 1 or two rows
Session is reset

I have interactive mode off, get and edit history are also off.
It seems to be specific to this component, or component type (the size?). Our Admins tell me it is a segmentation falt and the process is killed by the OS. Thanks Mr. OS! :)

There doesn't seem to be any Cobol or really intensive people code. Technically this shouldn't matter as interactive mode is turned off and I don't get to the point of saving, so it should be triggered.

I don't know if it matters, but I am going to check to see if 'Expert Entry' is enabled on the user that is connecting to the app server.

More to come....

Thursday, September 18, 2008

Using PL/SQL to Grant Permissions to Role(s) or Person(s)

When you have a large DB and it goes through an upgrade and _ALL_ the views have to be rebuild, that means that any/all permissions / Grants to those views are gone! (*sigh*) To quickly replace the permissions here is a little PL/SQL annonymous block to pull the view names, and grant permissions. Obviously this could be a lot intellegent and flexable, but here is the idea.

DECLARE
CURSOR myviews
IS
SELECT view_name
FROM SYS.user_views
WHERE view_name LIKE '%A_Z%';
BEGIN
FOR x IN myviews
LOOP
BEGIN
EXECUTE IMMEDIATE 'GRANT SELECT ON ' x.view_name ' TO COOL_PROGRAMMER';
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ( 'GRANT SELECT ON SYSADM.'
x.view_name
' TO COOL_PROGRAMMER; '
SQLERRM
);
END;
END LOOP;
END;

PeopleSoft: Stop Save of a page from PeopleCode

For some reason I had an issue figuring out how to stop the saving of a page… Then I was doing something completely unrelated and said, “DUH!!!”

 

To stop a save during validation in PeopleCode throw an error… Use only in the SaveEdit event. Don’t use it in FieldDefault, FieldFormula, RowInit, FieldChange, Prepopup, RowInsert, SavePreChange, or SavePostChange

 

Error  “Some String”;

 

You can use the MsgGet, MsgGetText functions too, if you add your own entries to the catalog.

 

PeopleCode: Change Options in a Drop down List

In PeopleSoft it is “easy” to change the drop down list options on Row-init …

This is from a co-worker. Used to change the options that students see for attendance (for specific class type)

If …… Then

/* Clear the current dropdown
values */
CLASS_ATTENDNCE.ATTEND_REASON.ClearDropDownList();
CLASS_ATTENDNCE.ATTEND_REASON.AddDropDownItem("ALCT", "Allowed
Cut"); CLASS_ATTENDNCE.ATTEND_REASON.AddDropDownItem("CANC",
"Cancelled"); CLASS_ATTENDNCE.ATTEND_REASON.AddDropDownItem("OTHR",
"Absent Other");
CLASS_ATTENDNCE.ATTEND_REASON.AddDropDownItem("PRES", "Present");
CLASS_ATTENDNCE.ATTEND_REASON.AddDropDownItem("SECT", "Second Cut");
CLASS_ATTENDNCE.ATTEND_REASON.AddDropDownItem("SICK", "Sick");

End-If;

Tuesday, September 16, 2008

Clean Up PeopleSoft Registry entries from CIs

Over the past couple of months I have made _alot_ of changes to my CIs and have had to
re-build then and re-register them etc etc... but the problem is that when I
have to update the client end, and re-register the tlb methods, I don't have a
'Clean-Up Entries' check box.

So.... To clean the registry from the last registered TLB, take the .reg file which starts:




[HKEY_CLASSES_ROOT\TypeLib\{D991A0F6-EFDC-480E-A3B7-DED9BB542536}\PeopleSoftGeneratedKey]
@="Sun Aug 31 23:45:09
2008"[HKEY_CLASSES_ROOT\TypeLib\{D991A0F6-EFDC-480E-A3B7-DED9BB542536}\1.0]
@="PeopleSoft_PeopleSoft"[HKEY_CLASSES_ROOT\TypeLib\{D991A0F6-EFDC-480E-A3B7-DED9BB542536}\1.0\0\win32]
@="c:\\ps\\8.49\\bin\\client\\winx86\\PeopleSoft_PeopleSoft.tlb"
Get your favorite text editor that has Regular expression capabilities (I use Crimson Editor, just casue it is free and does a lot of neat things).


Find: @.*
Replace with nothing

Find: \*\*.*
Replace with nothing


Turn off Regular Expression


Find: [
Replace with: [-


Copy and Paste the whole .Reg file to excel, and sort the column A-Z, to make the longest (deeper branches first) entries go to the top of each group, copy and paste it back to the reg file. Save it to a new name so you have your orignial, and then run it... the [-Branch Name] removes each entry.

Monday, September 15, 2008

CIs: Connecting to PeopleSoft Jolt sever from VB.net. Why & How. Part 4

[If you are looking to Load 100k+ rows into PeopleSoft quickly, this isn't the post for you! This is a multi post piece on Component Interfaces. Hopefully it is informative reading...]

Part 4

A nice thing about interactive mode is that is just that. If you set a field and that updates antoher, you can directly call that other field and the value is there. That is if InteractiveMode is turned on, of course.

Each level and scroll of the component buffer is setup as a collection that can be referenced directly or looped through as in the sample code. For each sub level0 collection there are methods for inserting and deleting items. To use 'Ci_collection.insertitem(x)' x equals Ci_collection.count.

In the sample Code you can see each level is in a For loop. This is good if you are reading out all the rows in the buffer, but for writing you want to jump to either insertingnewitem(collection.count) or oLvlTwo = oLvlTwoCollection.Item(5) unless you do need to cycle through them to find what you want to update etc. You don't need the 'set' statements in .Net. oLvlTwo = oLvlTwoCollection.Item(5) pulls item 5 from the collection and gives it to an object that allow access to that level's fields.

Another Key to CIs, especially in .Net is once you have saved or determined programatically that you don't need the CI anymore, cancel it. Use the .Cancel() function on the CI object. Each time you save, even if you are going to use the as CI again for a new transaction, cancel it and Get/Create it again. You can still read from it or change it in it current state, but once you want to move on to a new rowset etc, Cancel first.

One benifit of using CIs is that the user has to provide credentials, and have access in order to be able to use the CI. This means you are relying on out of the box functionality, which is always nice.

To bring this to a close, there is obviously a lot missing from these short posts, but the point was to point out that although Component Interfaces seem old technology and come with a bunch of over head, they can still be VERY useful when you need a custom solution to a problem and want to leverage the application tier.

Sunday, September 14, 2008

CIs: Connecting to PeopleSoft Jolt sever from VB.net. Why & How. Part 3


[If you are looking to Load 100k+ rows into PeopleSoft quickly, this isn't the post for you! This is a multi post piece on Component Interfaces. Hopefully it is informative reading...]
Part 3


The file is laid out in two Subs. ErrorHandler and main.

ErrorHandler is generic for all CIs. Call it often! One of the major issues I had to deal with was error handling. Wether you use PeopleCode or VB or Java, you must handle errors well. If a CI hits an error it freezes; just like in the web front end. Until you clear the messeges, the CI is unusable.

In using .Net, in the ErrorHandler sub there is a problem. The line:

oPSMessageCollection.DeleteAll

This clears all the messeges and thus allows the CI to continue. It returns a var bool type (Boolean) but the problem is that is in type format that .Net doesn't like. I have tried marshaling it Ctyping it  etc... to no avail. The only way I could maked it work as to late bind as an object and set the property.
 
Dim o As Object = oPSMessageCollection
      Try
        o.DeleteAll()
      Catch ex As Exception
msgbox("Problems clearing Msgs.")
       End Try

That was the source of a lot of greif in the begining... After I got that issue sorted out, CIs became an option.

The sample code is well documented and allows you to copy and paste a lot of stuff. 'Try' statements are handy for the major parts of Get / Find / Create, allowing you to retry and handle errors nicely. Notice the statements for writing data are commented out, and read only properties aren't available to be set.

The sample code also showing good practice in setting up the CI by setting the three modes for a component. InteractiveMode, GetHistoryItems and EditHistoryItems. If users don't need instant feed back for each item entered, you can increase performance by setting InteractiveMode = Flase as the app server will only process all the data items at Save time, therefore eliminating a lot of overhead.

MS Exchange 2007 Inbound SMTP

So I was playing with Exchange 2007....

All I can say is "wow"... M$ has done a lot of work and made turned out a very slick offering. Can be Very complicated and very flexable, but does well to help the admin along the way.

Everything was pretty straight forward in setup; even for a guy who is no windows pro by any stretch...

The one issue I did hit was getting an SMTP Recieve connector to accept incoming mail.

I had setup the hub transport on the primary server to accept SMTP on port 25 etc, etc, from all addresses etc, etc... (After failing to setup a locked down version, I delete it all and started over with a wide open setup -- which still failed...ugh)

I turned on protocol logging for the connector, and was watching the log file as I sent mail... I was always getting:

550 5.7.1 Unable to relay,

Then I found a post by Wilbert De Graaf at
http://forums.microsoft.com/technet/showpost.aspx?postid=742464&siteid=17&sb=0&d=1&at=7&ft=11&tf=0&pageid=2

Which discribed my issue and point to http://technet.microsoft.com/en-us/library/aa997170.aspx to solve it...

Short Version:

Each incoming SMTP connection (From untrusted servers...) connects as "ANONYMOUS LOGON" and this user has to have permission to accept incoming mail ie the permission to "SMTPAcceptAnyRecipient"...

to do this go to to Exchange Management Shell and run

Get-AdPermission -Identity "SMTP RECIVEVE Connector Name" format-table -view Identity

Look at the "NT AUTHORITY\ANONYMOUS LOGON" user and its rights.

Make sure it has 'ms-Exch-SMTP-Accept-Any-Recipient' not denied.

But I am guessing, since you have this issue that it is either denied or not there at all....

To add the correct permissions run:

Add-AdPermission -Identity "SMTP RECIVEVE Connector Name" -User "NT AUTHORITY\ANONYMOUS LOGON" -ExtendedRights ms-Exch-SMTP-Submit,ms-Exch-SMTP-Accept-Any-Recipient

it might tell you that it has one or more of these rights already... oh well... it adds the missing ones and you should be good to go.

Saturday, September 13, 2008

CIs: Connecting to PeopleSoft Jolt sever from VB.net. Why & How. Part 2

[If you are looking to Load 100k+ rows into PeopleSoft quickly, this isn't the post for you! This is a multi post piece on Component Interfaces. Hopefully it is informative reading...]

Part 2

Since to Topic of this post is CIs lets get started... (finally :)

To start using CIs we have to have our environment set up to handle using the COM object front end of the java classes that actually do the work. We have to have enviromental variables set:
If these already exist, obviously just add missing parts...

CLASSPATH=C:\PS\8.49\web\psjoa\psjoa.jar
PATH=C:\PS\8.49;C:\PS\8.49\jre\bin\client

C:\PS\8.49 is where my PeopleTools is located.

As for what is needed for a peopleTools CI only environmnet, you don't need to whole thing. Here are the files that are needed:Everything under .\jre and \webIn .\bin\client\winx86:
  • dbghelp.dll
  • msvcp71.dll
  • msvcr71.dll
  • psapiadapter.dll
  • psbtunicode.dll
  • pscmnutils.dll
  • pscompat.dll
  • pslibeay32.dll
  • pspetssl.dll
  • trio.dll
  • zlib1.dll
  • PeopleSoft_PeopleSoft.reg & PeopleSoft_PeopleSoft.tlb are what you get when you build the PeopleSoft APIs from appdesigner.

    Once the PeopleSoft_PeopleSoft.reg file is registered (More about cleaning up CI registry entries in a bit) you may need to restart to have the environmental variable available etc. (I've found that it does wonders, thanks M$). Add a reference to the Peoplesoft_peoplesoft.tlb to a .Net project. You can import the reference as to not have to type peoplesoft_peoplesoft all the time.
    In order to get familiar with the code, I'd like to suggest that you take a look at the demo code that you can generate by right clicking on your CI from app designer and selecting the generate visual basic template. This is in VB6-or-less layout in a .bas file.

    Stay tuned for part 3.

    Checking a Peron's Roles within PeopleCode

    For manually securing object or doing some kind of filtering, it is regularly useful to know what roles a person has in their user profile. Peoplesoft provides a global variable to give you access to the person’s roles.

    Example:

    Local array of string &Roles;

    Local integer &I;

    &Roles = %Roles;
    &doTransfer = True;

    For &I = &Roles.Len To 1 Step - 1
    If &Roles [&I] = "My Special Role" Then
    &doTransfer = False;
    End-If;
    End-For;

    Friday, September 12, 2008

    CIs: Connecting to PeopleSoft Jolt sever from VB.net. Why & How. Part 1

    [If you are looking to Load 100k+ rows into PeopleSoft quickly, this isn't the post for you! This is a multi post piece on Component Interfaces. Hopefully it is informative reading...]

    Part 1:

    There have been a lot of times when we have needed to mass load some sort of data. One of the main issues as always been load directly into PeopleSoft DB tables is just yucky... :) Some times unavoidable, but almost always yucky... I guess i should explain what i mean by yucky... The clearest example is person bio demo data. When you use 'add/update a person' to add a new person the emplid is give to you, the person's data is strewn over a plethora of tables and all the effective dating stuff is taken care of for you. Not to even touch on search match possibilities; cause we all love dupes so much...

    Moving data around between platforms is always a headache. Then there is the migraine called synchronizing data... anyway, say you have an application that really needs data moved from it to Oracle's PeopleSoft. You could write something to connect to both DB and just pass data back and forth, but you want a solution that is more flexible, able to be used by an end user (securing DB level access for end users, do i need to say more...) and you want to be able to leverage data validation from the application tier. Sounds great. You have two options: CI or Web service.

    As of 8.48, web services are a good option, but they are still lacking some (this could totally be from a lack of understanding from my part) and are a little ... um.. clunky?... when it comes to dealing with re-posts and data validation. They are great for posting small data objects from remote systems that you can almost be curtain the data is always good.

    I have come to really have an appreciation for CIs. At first I really didn't like them because of the fact that they are based on old COM objects, don't work too nicely with .Net (I now have some tricks... :), setting up the environment was a pain, maintaining distributions was painful too and they are inherently SLOW (slow-as-a-wet-week). After I overcame these little hurdles, or learnt to live with them, the results are quite workable.

    Windows Folder Share / Mapping Issue

    Just hit a problem... "The network folder is currently mapped with a different username/password" even though from "My Computer" I can't see anything mapped...

    Found an amazingly helpful blog at:
    http://travisepperson.blogspot.com/2007/01/windows-network-folder-specified-is.html

    Short version:
    dropped to command line i.e. "start Run cmd"
    Ran: net use

    found the the offending share.

    net use ">" /delete

    Re-map network drive. Worked like a charm!


    Thanks Mr. Epperson!!!!

    Create a MD5 Hash in VB.Net

    Creating a compliant MD5 Hash was a tough find for VB... I looked all over the place and found people doing all kinds of thing for hashes... But I needed one that would be the same as a Perl/PHP hash... After a lot of searching, I mashed together (as most of us do) a couple of ideas about the cryproservices and string building to come up with this...


    Imports System.Security.Cryptography

    Public Function Md5Hasher(ByVal StringToHash As String) As String
    Dim md5Crypter As MD5
    md5Crypter = MD5CryptoServiceProvider.Create
    Dim DataBytes() As Byte = md5Crypter.ComputeHash(Encoding.Default.GetBytes(StringToHash ))
    Dim strbldr As StringBuilder = New StringBuilder
    Dim i As Integer
    For i = 0 To DataBytes.Length - 1
    strbldr.AppendFormat("{0:x2}", dataMd5(i))
    Next

    Return strbldr .ToString

    End Function

    Oracle Data Reader to Data Table VB.Net

    One of the things that I don't like about Oracle's .Net Library is that sometimes you want more than the reader, but less than the DataAdapter.... So here is my little function to grab a reader and then return it as a data table. It returns nothing if there is nothing return


    Function GetReaderAsDataTable(ByVal sql As String, ByVal Envrionment As String, Optional ByRef OtherOraConnection As OracleConnection = Nothing) As DataTable
     Try
       Dim OutputDataTable As New DataTable
       Dim x As Integer
      
       Dim cmdfunc As New OracleCommand
      
       If OtherOraConnection Is Nothing Then
        Me.ConnectToOracle(Envrionment)
        cmdfunc.Connection = mbiUser_Admin.OracleFunctionlib.oraConnection
       Else
        cmdfunc.Connection = OtherOraConnection
       End If
      
       cmdfunc.CommandText = sql
       cmdfunc.CommandType = CommandType.Text
      
       Dim drFunc As OracleDataReader
       drFunc = cmdfunc.ExecuteReader
      
      
       If Not drFunc.HasRows Then
        Return Nothing
       Else
        Dim DataRowString(drFunc.FieldCount - 1)
        For x = 0 To drFunc.FieldCount - 1
         OutputDataTable.Columns.Add(drFunc.GetName(x), drFunc.GetFieldType(x))
        Next
        While drFunc.Read
         For x = 0 To drFunc.FieldCount - 1
          DataRowString(x) = drFunc(x)
         Next
         OutputDataTable.LoadDataRow(DataRowString, True)
        End While
      
        Return OutputDataTable
       End If
      
      Catch ex As Exception
       Try
        HttpContext.Current.Session("msg") = (ex.Message & vbLf & vbCr & sql)
       Catch ex1 As Exception
        'Not in a HTTP Session; you can do something with the msg if you want... like return it to the user would be nice... but with most of my stuff just knowing that the sql didn't return anything is good enough. Robust, no, but usable.
       End Try
      
       Return Nothing
      End Try
      
      
    End Function

    Monday, September 1, 2008

    Check an E-mail address with VB.NET Regex

    This is a VB.NET Function to Check an e-mail address with Regex...

    Function CheckValidEmail(Optional ByVal inputEmail As String = Nothing) As Boolean
    If inputEmail Is Nothing Then
    Return (False)
    End If
    Dim strRegex As String = "^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" + "\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" + ".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"
    Dim re As Regex = New Regex(strRegex)
    If re.IsMatch(inputEmail) Then
    Return (True)
    Else
    Return (False)
    End If

    End Function
    Add to Google