Solved

ASP VBScript Recordset Change to Array (with GETROWS)

Posted on 2012-03-27
9
698 Views
Last Modified: 2012-06-21
Hi,

I'm trying to move my ASP VB Script recordset code from being a recordset into being an array...

my code currently looks like --

<%
Dim RSPartner__MMColParam
RSPartner__MMColParam = 0
If (Request("i") <> "") Then 
  RSPartner__MMColParam = Request("i")
End If
%>
<%
Dim RSPartner
Dim RSPartner_cmd
Dim RSPartner_numRows

Set RSPartner_cmd = Server.CreateObject ("ADODB.Command")
RSPartner_cmd.ActiveConnection = MM_Connection_STRING
RSPartner_cmd.CommandText = "SELECT ID, FirstName, LastName, ClubName FROM dbo.Member WHERE ID <> ?" 
RSPartner_cmd.Prepared = true
RSPartner_cmd.Parameters.Append RSPartner_cmd.CreateParameter("param1", 5, 1, -1, RSPartner__MMColParam) ' adDouble

Set RSPartner = RSPartner_cmd.Execute
RSPartner_numRows = 0
%>

Open in new window


Is there an easy way of doing this? Do I just need to add something to the bottom?

Also, how do I limit the number of results returned, and how do I page through the results.. like 1|2|3|4.. etc..

Currently with Recordsets accessi9ng the database, i have some script on my page that creates the recorset navigation links like those listed above..

Please advise.

Thank you
0
Comment
Question by:garethtnash
  • 5
  • 4
9 Comments
 
LVL 28

Expert Comment

by:sammySeltzer
Comment Utility
You could use getRows() to accomplish this.

Dim RSPartner
Dim RSPartner_cmd
Dim RSPartner_numRows
 
Set RSPartner_cmd = Server.CreateObject ("ADODB.Command") 
RSPartner_cmd.ActiveConnection = MM_Connection_STRING 
RSPartner_cmd.CommandText = "SELECT ID, FirstName, LastName, ClubName FROM dbo.Member WHERE ID <> ?" 
RSPartner_cmd.Prepared = true 
 
Set RSPartner = RSPartner_cmd.Execute 
 
Dim arrPartner 
arrPartner = Partners.GetRows() 
 
dim i 
response.write "<table>" 
For i = 0 to ubound(arrPartner, 2) 
   response.write "<tr>" 
   response.write("<td>" + trim(i+1)) 
   response.write("<td>" + trim(arrPartner(0,i))) 
   response.write("<td>" + trim(arrPartner(1,i))) 
   response.write("<td>" + trim(arrPartner(2,i))) 
   response.write("<td>" + trim(arrPartner(3,i))) 
   response.write "</tr>" 
next 
response.write "</table>" 
%> 

Open in new window

0
 

Author Comment

by:garethtnash
Comment Utility
Thanks,

What does "ubound(arrProducts, 2)" do? specifically the 2 part?

Also I want to limit the number of results that are returned, how do I go about doing this?

I had --

<%
Dim RSPartner__MMColParam
RSPartner__MMColParam = "0"
If (Request("i") <> "") Then 
  RSPartner__MMColParam = Request("i")
End If
%>
<%
Dim RSPartner
Dim RSPartner_cmd
Dim RSPartner_numRows

Set RSPartner_cmd = Server.CreateObject ("ADODB.Command")
RSPartner_cmd.ActiveConnection = MM_Connection_STRING
RSPartner_cmd.CommandText = "SELECT ID, FirstName, LastName, ClubName FROM dbo.Member WHERE ID <> ?" 
RSPartner_cmd.Prepared = true
RSPartner_cmd.Parameters.Append RSPartner_cmd.CreateParameter("param1", 5, 1, -1, RSPartner__MMColParam) ' adDouble

Set RSPartner = RSPartner_cmd.Execute
RSPartner_numRows = 0

dim arrRSPartner
arrRSPartner = RSPartner.GetRows(15,0)
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
  <% 
dim i 
For i = 0 to ubound(arrRSPartner, 2)
%>
  <tr>
    <td><%=(trim(arrRSPartner(0,i)))%></td>
    <td><%=(trim(arrRSPartner(1,i)))%></td>
    <td><%=(trim(arrRSPartner(2,i)))%></td>
    <td><%=(trim(arrRSPartner(3,i)))%></td>
  </tr>
<%
next 
%>
</table>
</body>
</html>
<%
RSPartner.Close()
Set RSPartner = Nothing
%>

Open in new window


Which is returning the top 15 results, but I can't see how to return the next 15, I have tried editing the --

arrRSPartner = RSPartner.GetRows(15,0) section.

just with no joy..

Also I'm keeping the Server Side code, SErver Side, would this be the wrong thing to do?

Thanks
0
 
LVL 28

Expert Comment

by:sammySeltzer
Comment Utility
the 2 part means 2 dimensional array.

What code did you apply for paging?

Ok, let me see what I can do.
0
 
LVL 28

Expert Comment

by:sammySeltzer
Comment Utility
Not tested but try this and let me know if you run into errors.

<%
 Dim iStart, iOffset
  iStart = Request("Start")
  iOffset = Request("Offset")

  if Not IsNumeric(iStart) or Len(iStart) = 0 then
    iStart = 0
  else
    iStart = CInt(iStart)
  end if

  if Not IsNumeric(iOffset) or Len(iOffset) = 0 then
    iOffset = 10
  else
    iOffset = Cint(iOffset)
  end if

  Response.Write "Viewing " & iOffset & " records starting at record " & _
                 iStart & "<BR>"


Dim RSPartner
Dim RSPartner_cmd
Dim RSPartner_numRows
 
Set RSPartner_cmd = Server.CreateObject ("ADODB.Command") 
RSPartner_cmd.ActiveConnection = MM_Connection_STRING 
RSPartner_cmd.CommandText = "SELECT ID, FirstName, LastName, ClubName FROM dbo.Member WHERE ID <> ?" 
RSPartner_cmd.Prepared = true 
 
Set RSPartner = RSPartner_cmd.Execute 
 
Dim arrPartner 
arrPartner = Partners.GetRows() 
 
 If i > (iOffset + iStart) Then
    iStop = iOffset + iStart - 1
  Else
    iStop = i
  End If


dim i 
response.write "<table>" 
For i = 0 to ubound(arrProducts, 2) 
   response.write "<tr>" 
   response.write("<td>" + trim(i+1)) 
   response.write("<td>" + trim(arrPartner(0,i))) 
   response.write("<td>" + trim(arrPartner(1,i))) 
   response.write("<td>" + trim(arrPartner(2,i))) 
   response.write("<td>" + trim(arrPartner(3,i))) 
next 
response.write "</table>" 

response.Write "<P>"

if iStart > 0 then
    'Show Prev link
    Response.Write "<A HREF=""yourFileName.asp?Start=" & iStart-iOffset & _
                   "&Offset=" & iOffset & """>Previous " & iOffset & "</A>"
  end if

  if iStop < i then
    'Show Next link
    Response.Write " <A HREF=""yourFileName.asp?Start=" & iStart+iOffset & _
                   "&Offset=" & iOffset & """>Next " & iOffset & "</A>"
  end if
%>

Open in new window

0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:garethtnash
Comment Utility
Thanks Sammy, you have well gone the extra mile :) now I just need to try and understand what you have written... I'll o some testing to try and understand....

using your logic, can i create a recordset navigation bar like 1|2|3|4|5| Next> etc?

Thanks
0
 
LVL 28

Accepted Solution

by:
sammySeltzer earned 500 total points
Comment Utility
Well, I made some additional changes to add more comments for readability.

I tested this one and it works fine.

You just have to make the styling changes.

A couple of notes, you will need to replace my SELECT statement with yours.

You will also need to comment out the Access database I used for testing

Finally, be sure to change the file name at the bottom where I used getrows_b.asp

Good luck.


<%
Dim objConn, objRS, strSQL

  set MM_Connection_STRING=Server.CreateObject("ADODB.Connection")
  MM_Connection_STRING.Provider="Microsoft.Jet.OLEDB.4.0"
  MM_Connection_STRING.Open Server.MapPath("Paging.mdb")

Set RSPartner_cmd = Server.CreateObject ("ADODB.Command")
RSPartner_cmd.ActiveConnection = MM_Connection_STRING
RSPartner_cmd.CommandText = "SELECT ID, VRRequestorsName, VRRequestorsEmail, VRStaffType From GenMain"
RSPartner_cmd.Prepared = true

Set RSPartner = RSPartner_cmd.Execute

'Set objRS = Server.CreateObject("ADODB.Recordset")
'objRS.Open strSQL, objConn

Dim arrPartners
arrPartners = RSPartner.GetRows()

 RSPartner.close
 set RSPartner=nothing
  MM_Connection_STRING.Close
  Set MM_Connection_STRING = Nothing


 '<------------- Paging Begins------------>
  Dim pageStart, pageSize
  pageStart = Request("Start")
  pageSize = Request("Offset")

  if Not IsNumeric(pageStart) or Len(pageStart) = 0 then
    pageStart = 0
  else
    pageStart = CInt(pageStart)
  end if

  if Not IsNumeric(pageSize) or Len(pageSize) = 0 then
    pageSize = 5 'Show only 5 pages. ***********You can increase to 15. I used 5 for testing
  else
    pageSize = Cint(pageSize)
  end if

  Dim i, iCols, iRowLoop, iColLoop, pageStop
  i = UBound(arrPartners, 2)
  iCols = UBound(arrPartners, 1)

  If i > (pageSize + pageStart) Then
    pageStop = pageSize + pageStart - 1
  Else
    pageStop = i
  End If

  Response.Write "<P>"

'********  Create table for the results
Body = "<table border=1 bordercolor=gainsboro cellspacing=0 cellpadding=0>" & vblf & _
"<span style='text-align:center; font-size:12pt;font-weight:bold;'>Results</span>" & vblf
'loop thru the results
for iRowLoop = pageStart to pageStop
  Body = Body & "<tr>" & vblf & _
  "<td>" & arrPartners(0,iRowLoop) & "</td>" & _
  "<td>" & arrPartners(1,iRowLoop) & "</td>" & _
  "<td>" & arrPartners(2,iRowLoop) & "</td>" & _
  "<td>" & arrPartners(3,iRowLoop) & "</td>" & _
  "</tr>" & vblf
next
Body = Body & "</table>" & vblf


'**********  Navigation and styling

Body = Body & "<p>Displaying record " & pageStart + 1 & " to " & pageStop + 1 & " of " & uBound(arrPartners,2) + 1 & " total. " & vblf
  if pageStart > 0 then
    'previous page link
    Body = Body & "| <a href=""getrows_b.asp?start=" & pageStart-pageSize & "&amp;offset=" & pageSize & _
    """>Previous page</a>" & vblf
  end if
  if pageStop < i then
    'next page link
    Body = Body & " | <a href=""getrows_b.asp?start=" & pageStart+pageSize & "&amp;offset=" & pageSize & _
    """>Next page</a>" & vblf
  end if

'print everything
response.write Body

%>

Open in new window

0
 

Author Comment

by:garethtnash
Comment Utility
Hi Sammy,

Thank you, one more quetion, can i e a varient of "arrPartners(0,iRowLoop)" to get random value from the column?

 Thank you
0
 

Author Comment

by:garethtnash
Comment Utility
Hi Sammy,

Just looking at the existing recordset navigation code, that produces the 1|2|3|4|5 type navigation bar...

my code currenly looks like --

<%
TFM_MiddlePages = 5
TFM_delimiter = ""
TFM_startLink = MM_offset + 1 - MM_size * (int(TFM_middlePages/2))
If MM_offset > 0 Then TFM_LimitPageEndCount = int(TFM_startLink/MM_size)
If TFM_startLink < 1 Then 
	TFM_startLink = 1
	TFM_LimitPageEndCount = 0
End If
TFM_endLink = MM_size * TFM_MiddlePages + TFM_startLink - 1
If TFM_endLink > RSPartnerList_total Then TFM_endLink = RSPartnerList_total 
For i = TFM_startLink to TFM_endLink Step MM_size
  TFM_LimitPageEndCount = TFM_LimitPageEndCount + 1
  if i <> MM_offset + 1 Then
    Response.Write("<li><a href=""" & Request.ServerVariables("URL") & "?" & MM_keepMove & "offset=" & i-1 & """>")
    Response.Write(TFM_LimitPageEndCount & "</a></li>")
  else
    Response.Write("<li><strong>")
    Response.Write(TFM_LimitPageEndCount & "</strong></li>")
  End if
  if(i <= TFM_endLink - MM_size) then Response.Write(TFM_delimiter)
Next
%>

Open in new window


Which seems tyo be utilising the parameters

MM_offset
MM_size
RSPartnerList_total
MM_keepMove

Which have been previously created.

In this mass of code --

<%
'  *** Recordset Stats, Move To Record, and Go To Record: declare stats variables

Dim RSPartnerList_total
Dim RSPartnerList_first
Dim RSPartnerList_last

' set the record count
RSPartnerList_total = RSPartnerList.RecordCount

' set the number of rows displayed on this page
If (RSPartnerList_numRows < 0) Then
  RSPartnerList_numRows = RSPartnerList_total
Elseif (RSPartnerList_numRows = 0) Then
  RSPartnerList_numRows = 1
End If

' set the first and last displayed record
RSPartnerList_first = 1
RSPartnerList_last  = RSPartnerList_first + RSPartnerList_numRows - 1

' if we have the correct record count, check the other stats
If (RSPartnerList_total <> -1) Then
  If (RSPartnerList_first > RSPartnerList_total) Then
    RSPartnerList_first = RSPartnerList_total
  End If
  If (RSPartnerList_last > RSPartnerList_total) Then
    RSPartnerList_last = RSPartnerList_total
  End If
  If (RSPartnerList_numRows > RSPartnerList_total) Then
    RSPartnerList_numRows = RSPartnerList_total
  End If
End If
%>
<%
' *** Recordset Stats: if we don't know the record count, manually count them

If (RSPartnerList_total = -1) Then

  ' count the total records by iterating through the recordset
  RSPartnerList_total=0
  While (Not RSPartnerList.EOF)
    RSPartnerList_total = RSPartnerList_total + 1
    RSPartnerList.MoveNext
  Wend

  ' reset the cursor to the beginning
  If (RSPartnerList.CursorType > 0) Then
    RSPartnerList.MoveFirst
  Else
    RSPartnerList.Requery
  End If

  ' set the number of rows displayed on this page
  If (RSPartnerList_numRows < 0 Or RSPartnerList_numRows > RSPartnerList_total) Then
    RSPartnerList_numRows = RSPartnerList_total
  End If

  ' set the first and last displayed record
  RSPartnerList_first = 1
  RSPartnerList_last = RSPartnerList_first + RSPartnerList_numRows - 1
  
  If (RSPartnerList_first > RSPartnerList_total) Then
    RSPartnerList_first = RSPartnerList_total
  End If
  If (RSPartnerList_last > RSPartnerList_total) Then
    RSPartnerList_last = RSPartnerList_total
  End If

End If
%>
<%
Dim MM_paramName 
%>
<%
' *** Move To Record and Go To Record: declare variables

Dim MM_rs
Dim MM_rsCount
Dim MM_size
Dim MM_uniqueCol
Dim MM_offset
Dim MM_atTotal
Dim MM_paramIsDefined

Dim MM_param
Dim MM_index

Set MM_rs    = RSPartnerList
MM_rsCount   = RSPartnerList_total
MM_size      = RSPartnerList_numRows
MM_uniqueCol = ""
MM_paramName = ""
MM_offset = 0
MM_atTotal = false
MM_paramIsDefined = false
If (MM_paramName <> "") Then
  MM_paramIsDefined = (Request.QueryString(MM_paramName) <> "")
End If
%>
<%
' *** Move To Record: handle 'index' or 'offset' parameter

if (Not MM_paramIsDefined And MM_rsCount <> 0) then

  ' use index parameter if defined, otherwise use offset parameter
  MM_param = Request.QueryString("index")
  If (MM_param = "") Then
    MM_param = Request.QueryString("offset")
  End If
  If (MM_param <> "") Then
    MM_offset = Int(MM_param)
  End If

  ' if we have a record count, check if we are past the end of the recordset
  If (MM_rsCount <> -1) Then
    If (MM_offset >= MM_rsCount Or MM_offset = -1) Then  ' past end or move last
      If ((MM_rsCount Mod MM_size) > 0) Then         ' last page not a full repeat region
        MM_offset = MM_rsCount - (MM_rsCount Mod MM_size)
      Else
        MM_offset = MM_rsCount - MM_size
      End If
    End If
  End If

  ' move the cursor to the selected record
  MM_index = 0
  While ((Not MM_rs.EOF) And (MM_index < MM_offset Or MM_offset = -1))
    MM_rs.MoveNext
    MM_index = MM_index + 1
  Wend
  If (MM_rs.EOF) Then 
    MM_offset = MM_index  ' set MM_offset to the last possible record
  End If

End If
%>
<%
' *** Move To Record: if we dont know the record count, check the display range

If (MM_rsCount = -1) Then

  ' walk to the end of the display range for this page
  MM_index = MM_offset
  While (Not MM_rs.EOF And (MM_size < 0 Or MM_index < MM_offset + MM_size))
    MM_rs.MoveNext
    MM_index = MM_index + 1
  Wend

  ' if we walked off the end of the recordset, set MM_rsCount and MM_size
  If (MM_rs.EOF) Then
    MM_rsCount = MM_index
    If (MM_size < 0 Or MM_size > MM_rsCount) Then
      MM_size = MM_rsCount
    End If
  End If

  ' if we walked off the end, set the offset based on page size
  If (MM_rs.EOF And Not MM_paramIsDefined) Then
    If (MM_offset > MM_rsCount - MM_size Or MM_offset = -1) Then
      If ((MM_rsCount Mod MM_size) > 0) Then
        MM_offset = MM_rsCount - (MM_rsCount Mod MM_size)
      Else
        MM_offset = MM_rsCount - MM_size
      End If
    End If
  End If

  ' reset the cursor to the beginning
  If (MM_rs.CursorType > 0) Then
    MM_rs.MoveFirst
  Else
    MM_rs.Requery
  End If

  ' move the cursor to the selected record
  MM_index = 0
  While (Not MM_rs.EOF And MM_index < MM_offset)
    MM_rs.MoveNext
    MM_index = MM_index + 1
  Wend
End If
%>
<%
' *** Move To Record: update recordset stats

' set the first and last displayed record
RSPartnerList_first = MM_offset + 1
RSPartnerList_last  = MM_offset + MM_size

If (MM_rsCount <> -1) Then
  If (RSPartnerList_first > MM_rsCount) Then
    RSPartnerList_first = MM_rsCount
  End If
  If (RSPartnerList_last > MM_rsCount) Then
    RSPartnerList_last = MM_rsCount
  End If
End If

' set the boolean used by hide region to check if we are on the last record
MM_atTotal = (MM_rsCount <> -1 And MM_offset + MM_size >= MM_rsCount)
%>
<%
' *** Go To Record and Move To Record: create strings for maintaining URL and Form parameters

Dim MM_keepNone
Dim MM_keepURL
Dim MM_keepForm
Dim MM_keepBoth

Dim MM_removeList
Dim MM_item
Dim MM_nextItem

' create the list of parameters which should not be maintained
MM_removeList = "&index="
If (MM_paramName <> "") Then
  MM_removeList = MM_removeList & "&" & MM_paramName & "="
End If

MM_keepURL=""
MM_keepForm=""
MM_keepBoth=""
MM_keepNone=""

' add the URL parameters to the MM_keepURL string
For Each MM_item In Request.QueryString
  MM_nextItem = "&" & MM_item & "="
  If (InStr(1,MM_removeList,MM_nextItem,1) = 0) Then
    MM_keepURL = MM_keepURL & MM_nextItem & Server.URLencode(Request.QueryString(MM_item))
  End If
Next

' add the Form variables to the MM_keepForm string
For Each MM_item In Request.Form
  MM_nextItem = "&" & MM_item & "="
  If (InStr(1,MM_removeList,MM_nextItem,1) = 0) Then
    MM_keepForm = MM_keepForm & MM_nextItem & Server.URLencode(Request.Form(MM_item))
  End If
Next

' create the Form + URL string and remove the intial '&' from each of the strings
MM_keepBoth = MM_keepURL & MM_keepForm
If (MM_keepBoth <> "") Then 
  MM_keepBoth = Right(MM_keepBoth, Len(MM_keepBoth) - 1)
End If
If (MM_keepURL <> "")  Then
  MM_keepURL  = Right(MM_keepURL, Len(MM_keepURL) - 1)
End If
If (MM_keepForm <> "") Then
  MM_keepForm = Right(MM_keepForm, Len(MM_keepForm) - 1)
End If

' a utility function used for adding additional parameters to these strings
Function MM_joinChar(firstItem)
  If (firstItem <> "") Then
    MM_joinChar = "&"
  Else
    MM_joinChar = ""
  End If
End Function
%>
<%
' *** Move To Record: set the strings for the first, last, next, and previous links

Dim MM_keepMove
Dim MM_moveParam
Dim MM_moveFirst
Dim MM_moveLast
Dim MM_moveNext
Dim MM_movePrev

Dim MM_urlStr
Dim MM_paramList
Dim MM_paramIndex
Dim MM_nextParam

MM_keepMove = MM_keepBoth
MM_moveParam = "index"

' if the page has a repeated region, remove 'offset' from the maintained parameters
If (MM_size > 1) Then
  MM_moveParam = "offset"
  If (MM_keepMove <> "") Then
    MM_paramList = Split(MM_keepMove, "&")
    MM_keepMove = ""
    For MM_paramIndex = 0 To UBound(MM_paramList)
      MM_nextParam = Left(MM_paramList(MM_paramIndex), InStr(MM_paramList(MM_paramIndex),"=") - 1)
      If (StrComp(MM_nextParam,MM_moveParam,1) <> 0) Then
        MM_keepMove = MM_keepMove & "&" & MM_paramList(MM_paramIndex)
      End If
    Next
    If (MM_keepMove <> "") Then
      MM_keepMove = Right(MM_keepMove, Len(MM_keepMove) - 1)
    End If
  End If
End If

' set the strings for the move to links
If (MM_keepMove <> "") Then 
  MM_keepMove = Server.HTMLEncode(MM_keepMove) & "&"
End If

MM_urlStr = Request.ServerVariables("URL") & "?" & MM_keepMove & MM_moveParam & "="

MM_moveFirst = MM_urlStr & "0"
MM_moveLast  = MM_urlStr & "-1"
MM_moveNext  = MM_urlStr & CStr(MM_offset + MM_size)
If (MM_offset - MM_size < 0) Then
  MM_movePrev = MM_urlStr & "0"
Else
  MM_movePrev = MM_urlStr & CStr(MM_offset - MM_size)
End If
%>

Open in new window


Fancy a challenge? From what I can see, with arrays, a good chunk of the second section of code would be redundent?

Thanks for your help with this so far, you have been fantastic :)
0
 

Author Closing Comment

by:garethtnash
Comment Utility
Excellent - thank you
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

This demonstration started out as a follow up to some recently posted questions on the subject of logging in: http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/Q_28634665.html and http://www.experts-exchange.com/Programming/…
Building a website can seem like a daunting task to the uninitiated but it really only requires knowledge of two basic languages: HTML and CSS.
In this tutorial viewers will learn how to style transparent/translucent elements using alpha transparency in CSS Start with a normal styled element, such as a div.: Define its "background-color" property as "rgba (255, 255, 255, .5): The numbers in…
HTML5 has deprecated a few of the older ways of showing media as well as offering up a new way to create games and animations. Audio, video, and canvas are just a few of the adjustments made between XHTML and HTML5. As we learned in our last micr…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now