Posts by Justin Doward
-
-
I have used this technique before, and the previous forms I have made do work still, but for some reason whenever I try to open .pdf files with the webbrowser on a form now it crashes. In the attached file if you create a c:\test directory it should list the files in the test directory in the listbox when you select from the combobox, it then works to open jpg, xlsx, doc and whatever else is there except pdf files, when you select them from the listbox.
The attachment is a stripped down version of my working document, but it has the same issue.Book1.xlsm
Can anyone let me know why this might not be working, and whether you have the same trouble if you test the file?
-
Hi Victor,
I think the approach in the form is incredibly over-complicated for the expected outcome.
I have put an alternative approach in the attachment here, double click on the cell (C14-C25) to open the form, type in the textbox to search then select from the listbox to fill the cell that was doubleclicked.
-
Hi Victor,
Try this code in the code for the sheet:
Code
Display MoreSub Worksheet_Change(ByVal Target As Range) If Not Intersect(Target, Range("H14:H25")) Is Nothing Then Dim x As Long, MyBool As Boolean Dim ws2 As Worksheet: Set ws2 = Sheet2 Dim ws3 As Worksheet: Set ws3 = Sheet3 x = Application.Match(Range("B" & Target.Row), ws2.Range("B4:B500"), 0) MyBool = False If IsNumeric(x) Then For i = 7 To Columns.Count If ws2.Cells(1, i).EntireColumn.Hidden = False Then ws2.Range("G" & x + 3).Offset(0, i - 7) = ws2.Range("G" & x + 3).Offset(0, i - 7).Value2 + CStr(Target.Value) If MyBool = False Then Call XShts(Target.Row) MyBool = True GoTo MyEnd End If Next i End If End If MyEnd: End Sub
And this code in a module:
Code
Display MoreSub XShts(TgtRW As Long) GoTo MyStart MyErr: MsgBox "Error: Worksheet listed in G9 may not exist" GoTo MyEnd MyStart: On Error GoTo MyErr Dim ws3 As Worksheet: Set ws3 = Sheet3 If Len(ws3.Range("G9")) Then Dim wsX As Worksheet: Set wsX = Worksheets(Range("G9").Value2) Dim MyXRW As Long MyXRW = Application.Match(Range("B" & TgtRW), wsX.Range("B6:B500"), 0) + 5 If IsNumeric(MyXRW) Then wsX.Range("G" & MyXRW) = wsX.Range("G" & MyXRW) & CStr(ws3.Range("H" & TgtRW)) End If MyEnd: End Sub
Change your drop down in G9 to reflect the sheet names not their references.
Let me know how it goes.
-
Okay, I think we got there. It makes sense now.
Code
Display MoreSub Worksheet_Change(ByVal Target As Range) If Not Intersect(Target, Range("H14:H25")) Is Nothing Then Dim ws2 As Worksheet: Set ws2 = Sheet2 Dim ws3 As Worksheet: Set ws3 = Sheet3 x = Application.Match(Range("B" & Target.Row), ws2.Range("B4:B500"), 0) If IsNumeric(x) Then For i = 7 To Columns.Count If ws2.Cells(1, i).EntireColumn.Hidden = False Then ws2.Range("G" & x + 3).Offset(0, i - 7) = ws2.Range("G" & x + 3).Offset(0, i - 7).Value2 & CStr(Target.Value) GoTo MyEnd End If Next i End If End If MyEnd: End Sub
If this has solved it, can you mark it as the answer on stack exchange as well. Cheers Justin
-
Hi Victor,
Again, I think this is what you are after however I am confused by having the entry cell in H now and the changed cell in G since this means the loop to look for hidden columns is redundant?
Code
Display MoreSub Worksheet_Change(ByVal Target As Range) If Not Intersect(Target, Range("H14:H25")) Is Nothing Then Dim ws2 As Worksheet: Set ws2 = Sheet2 Dim ws3 As Worksheet: Set ws3 = Sheet3 x = Application.Match(Range("B" & Target.Row), ws2.Range("B4:B500"), 0) If IsNumeric(x) Then For i = 7 To Columns.Count If ws3.Cells(1, i).EntireColumn.Hidden = False Then ws3.Range("G" & Target.Row).Offset(0, i - 7) = ws3.Range("G" & Target.Row).Offset(0, i - 7).Value2 & CStr(Target.Value) GoTo MyEnd End If Next i End If End If MyEnd: End Sub
-
Alternatively you could try a loop like:
CodeSub copyRWs() Application.ScreenUpdating = False Dim a a = Application.Transpose(Sheet1.Range("O2:O" & Sheet1.Cells(Rows.Count, "O").End(xlUp).Row)) 'creates array from O2:last row For i = LBound(a) To UBound(a) Sheet1.Rows(i + 1).EntireRow.copy (Sheets(a(i)).Cells(Sheets(a(i)).Cells(Rows.Count, 14).End(xlUp).Row + 1, 1)) 'copies each row Next i Application.ScreenUpdating = True End Sub
This assumes you have a table starting on row 1, change sheet1 to your sheetname , if jolivanes nor my response achieve what you are after an example worksheet is probably needed.
-
Hi M1,
You can try this:
Code
Display MoreSub delblankRC() Application.ScreenUpdating = False Dim ws1 As Worksheet: Set ws1 = Sheet1 Dim x As Long, y As Long, myR As Long, myC As Long x = ws1.UsedRange.Rows.Count y = ws1.UsedRange.Columns.Count For myR = x To 1 Step -1 If Application.CountA(ws1.Cells(myR, 1).EntireRow) = 0 Then ws1.Cells(myR, 1).EntireRow.Delete Next myR For myC = y To 1 Step -1 If Application.CountA(ws1.Cells(1, myC).EntireColumn) = 0 Then ws1.Cells(1, myC).EntireColumn.Delete Next myC Application.ScreenUpdating = True End Sub
-
The macro record function is very useful to identify the code required to complete a task but it does not do it efficiently, it records everything including when you scroll down the page or switch sheets etc... It is generally not necessary for these functions to occur when using code so you can go through and delete the scroll, select and activate portions of the code however you then will need to slightly modify the syntax of the code to allow for what you have changed.
You can often replace 10 lines of recorded macro with a single line once you know the appropriate syntax.
-
What is your definition of "huge data"? and what do you want to do with it?
-
If you are still after a macro solution, I think this does what you are after - try the button on the sheet.
Code
Display MoreSub copytables() Application.ScreenUpdating = False Dim ws1 As Worksheet: Set ws1 = Sheet1 Dim ws2 As Worksheet: Set ws2 = Sheet2 Dim MyList(3) As Variant ' change 3 to the number of table names you have Dim MyTable As Variant Dim Rnge1 As Range, c As Range Dim x As Long, i As Long, n As Long, p As Long Set Rnge1 = ws1.UsedRange MyList(0) = "Table1" ' change these names MyList(1) = "Table2" MyList(2) = "Table3" MyList(3) = "Table4" i = 1 For x = LBound(MyList) To UBound(MyList) n = 0 p = 1 For Each c In Rnge1 If c.Value = MyList(x) Then MyTable = c.CurrentRegion If UBound(MyTable, 1) > n Then n = UBound(MyTable, 1) c.CurrentRegion.Copy (ws2.Cells(i + 1, p).Resize(UBound(MyTable, 1), UBound(MyTable, 2))) p = p + UBound(MyTable, 2) + 1 End If Next c i = i + n + 1 Next x Application.ScreenUpdating = True End Sub
-
Hi Alhagag, you can try this:
Code
Display MoreSub After0() Dim lstrw As Long, x As Long Dim ws As Worksheet: Set ws = Worksheets("account") Dim ws2 As Worksheet: Set ws2 = Worksheets("result") Dim MyArr As Variant lstrw = ws.Cells(Rows.Count, "E").End(xlUp).Row For x = lstrw To 6 Step -1 If ws.Cells(x, "E").Value2 = 0 Then lstrw = x + 1 MyArr = ws.Range("A" & lstrw & ":H" & ws.Cells(Rows.Count, "H").End(xlUp).Row) ws2.Range("A" & ws2.Cells(Rows.Count, "A").End(xlUp).Row + 1).Resize(UBound(MyArr, 1), UBound(MyArr, 2)) = MyArr GoTo MyExit End If Next x MyExit: End Sub
It works on the example you sent.
-
that is true, but depending on the size of the data set maybe it is preferable? Or alternatively a couple of array formulas or or tables, but I have never been good at them. The solution you provided did not summarise the results so I used the code I know.
-
Hi HE,
Your example sheet does not appear to make sense with reference to your question, for example "Date Completed" appears as a field in sheet 3 as column B but column Q from sheet 1 is not one of the columns you are trying to copy from sheet1 (according to your question). Additionally your complaint numbers on sheet2 in no way align with the complaint numbers on sheet1.
I think I know what you are trying to do, i.e. copy the relevant information for a particular complaint from sheet1 to sheet 3 if there is a line Y in sheet 2 column Z but this is not really clear from the your post.
This code in the sheet should work to some extent if modified to suit.
Code
Display MorePrivate Sub Worksheet_Change(ByVal Target As Range) Application.ScreenUpdating = False Dim MycopyRW As Long, MytargRW As Long, MyREMRW As Long Dim wscopy As Worksheet: Set wscopy = Sheet3 Dim wstarg As Worksheet: Set wstarg = Sheet4 If Not Intersect(Target, Columns(26)) Is Nothing Then On Error GoTo MyExit If Target.Value2 = "Y" Then MycopyRW = Application.Match(Cells(Target.Row, 1), wscopy.Columns(1), 0) MytargRW = wstarg.Cells(Rows.Count, 1).End(xlUp).Row + 1 wstarg.Range("A" & MytargRW) = wscopy.Range("A" & MycopyRW) wstarg.Range("B" & MytargRW) = wscopy.Range("B" & MycopyRW) wstarg.Range("C" & MytargRW) = wscopy.Range("D" & MycopyRW) wstarg.Range("D" & MytargRW) = wscopy.Range("H" & MycopyRW) wstarg.Range("E" & MytargRW) = wscopy.Range("I" & MycopyRW) wstarg.Range("F" & MytargRW) = wscopy.Range("J" & MycopyRW) wstarg.Range("G" & MytargRW) = wscopy.Range("K" & MycopyRW) wstarg.Range("H" & MytargRW) = wscopy.Range("S" & MycopyRW) End If If Target.Value2 = "" Then MyREMRW = Application.Match(Cells(Target.Row, 1), wstarg.Columns(1), 0) wstarg.Rows(MyREMRW).EntireRow.Delete End If End If MyExit: Application.ScreenUpdating = True End Sub
As in the attachment it assumes a unique complaint ID, which may or may not be correct?
-
Hi HO,
You could try something like the attached, the macro is in module 1 of the attachment (as below).
There is a small button on the summary sheet in A1 to activate the macro.
Code
Display MoreOption Explicit Sub Options() Application.ScreenUpdating = False 'turn off screenupdating to speed up code Dim MatchCL As Long, S1LastRW As Long, S1LastCL As Long, x As Long, y As Long S1LastCL = Sheet1.Cells(1, Columns.Count).End(xlToLeft).Column 'find last used column on sheet1 S1LastRW = Sheet1.Cells(Rows.Count, 1).End(xlUp).Row 'find last used row on sheet1 For x = 2 To S1LastCL 'work through columns in sheet1, starting column 2 MatchCL = Application.Match(Sheet1.Cells(1, x), Sheet2.Rows(1), 0) 'find the column on sheet2 containing current option For y = 2 To S1LastRW 'work through each ID If Sheet1.Cells(y, x) = "Y" Then Sheet2.Cells(Sheet2.Cells(Rows.Count, MatchCL).End(xlUp).Row + 1, MatchCL - 1) = Sheet1.Cells(y, 1).Value2 'fill the ID Sheet2.Cells(Sheet2.Cells(Rows.Count, MatchCL).End(xlUp).Row + 1, MatchCL) = "Y" 'Fill the option End If Next y Next x Application.ScreenUpdating = True End Sub
-
Roy,
It was cross posted and he already has the solution.
-
Hi PO,
It is a little difficult to workout what you are trying to do exactly, I think from what you have described that you have all of your pictures in a single row? However it is not clear. If this is the case then you would wind up overwriting each file as the code you provided takes the name from the row of the picture and column A. It is not however clear how you do intend to name your files, where is the file name located in reference to the picture?
An example sheet would of course help.
-
Hello, thank you for reading:
I have a workbook with timed events using Application.Ontime referencing a global variable (GlobalTimer) that either opens a form (called TimeOut), or closes the workbook (to prevent users leaving a workbook open on a networked drive preventing others from using it). The form that opens is a warning that the sheet will close in x minutes unless a response is obtained, the form itself then closes after a few seconds.
This all works well except if windows is locked in which case the Application.WindowState = xlMaximized and Userform.Show commands do not run until the computer is reopened and if minimised the icon in the command bar clicked on.
Is there a way to detect if lines have failed/is failing to display the form and subsequently simply close the workbook?
NB: If I simply want to close the workbook, without giving warning, this works fine even if the computer is locked. it is just the loading of the form while the computer is locked that is causing an issue.
the code in the workbook is like this:
Code
Display MorePrivate Sub Workbook_Open() ThisBook = Application.ActiveWorkbook.Name 'set the variable to the current time GlobalTimer = Now() 'Opening workbook so check in 40sec minutes Application.OnTime Now() + TimeValue("00:00:40"), "CheckTimer1" Application.OnTime Now() + TimeValue("00:02:00"), "CheckTimer2" FRONT.Activate Call HideShts FRONT.ScrollArea = "A1" FRONT.Protect 'SHOWDIRECTORY End Sub Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range) GlobalTimer = Now() End Sub
The code in the module:
Code
Display MoreOption Explicit Public GlobalTimer As Date Public ThisBook As String Public Function ClsTIMEOUT() Unload TIMEOUT End Function Public Function CheckTimer1() As Boolean Dim x As Long 'check to see if we have a 5 minute interval TIMEOUT.Show If DateDiff("n", GlobalTimer, Now()) >= 0.5 Then Call SavenClose Else 'check again in x amount of minutes - currently it is .5 minutes Application.OnTime Now() + TimeValue("00:00:30"), "CheckTimer1" End If End Function Public Function CheckTimer2() As Boolean Dim x As Long 'check to see if we have a 5 minute interval 'Application.WindowState = xlMaximized 'TIMEOUT.Show If DateDiff("n", GlobalTimer, Now()) >= 0.5 Then Call SavenClose Else 'check again in x amount of minutes - currently it is .5 minutes Application.OnTime Now() + TimeValue("00:00:30"), "CheckTimer2" End If End Function Sub SavenClose() Dim frm As UserForm For Each frm In UserForms Unload frm Next frm On Error Resume Next Application.DisplayAlerts = False Workbooks(ThisBook).Saved = True Workbooks(ThisBook).Close Application.DisplayAlerts = True Application.ScreenUpdating = True End Sub
The code linked to the form:
CodePrivate Sub UserForm_Activate() Dim MyTime As Date MyTime = Now() Application.OnTime MyTime + TimeValue("00:00:05"), "ClsTIMEOUT" End Sub
There are a couple of buttons on the form that either change the globaltimer or does nothing.
-
That makes sense, I usually just use that to format a date in a text box on a form when displaying from a sheet I had not made the connection that it converted the result to text because I still use cDate to copy it from text onto a sheet (without the format because it is unnecessary) Thank you for the pointer.
-
Hi NA,
Try using the cDate function in your code, something like:
Cells(emptyRow, 2).Value = format(cDate(Date_Box.Value), "Short Date")