I have an MS Access VBA code that generates an Excel spreadsheet shown below, and I need to make my page break output from this:
into this:
programmatically in MS Access VBA.
I have tried already a bunch of codes (see snippets below) but somehow none of them did the trick nor even the slightest change.
Code Snippet #1)
ActiveWindow.View = xlPageBreakPreview
ActiveSheet.ResetAllPageBreaks
i = 1
If ActiveSheet.HPageBreaks.Count > 0 Then
Do
Set ActiveSheet.HPageBreaks(i).Location = Range("A" & (i * 70) + 1)
If i = ActiveSheet.HPageBreaks.Count Then Exit Do
i = i + 1
Loop
End If
Do Until Cells((i * 70) + 3, 1).Value = ""
ActiveSheet.HPageBreaks.Add Before:=Range("a" & (i * 73) + 1)
i = i + 1
Loop
ActiveWindow.View = xlNormalView
Code Snippet #2)
Dim Rng As Excel.Range
Set Rng = xls.Rows("1:75")
Rng(75).PageBreak = -4135
Code Snippet #3)
xls.HPageBreaks.Add Before:=xls.Cells(73, 1)
Any assistance on this is highly appreciated. Thanks a bunch! :)
I'm not understanding your snippets very well, but based on the screenshot, you want to print it on one page containing everything. Something like this sets the print area to 1 page x 1 page in excel -
Sub breaks()
Dim rLastCol As Long
Dim rLastRow As Long
With ActiveSheet
rLastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
rLastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
With .PageSetup
.PrintArea = Range("A1", Cells(rLastRow, rLastCol)).Address
.FitToPagesWide = 1
.FitToPagesTall = False
End With
End With
End Sub
Of course, this uses the last used cell in column A and in Row 1, so the most bottom-right non-blank.
Related
I am currently working on the following excel sheet:
this is the excel sheet
I am quite new to Excel and I just found out about the VBA function. Do you guys think that it is possible to write a code that does essentially the following:
If [Total Debt Stock] -> select the next 6 cells below and add to these cells "TDS" at the beginning.
And follwing this: If [short-term debt] -> select the next 2 (for instance) cells below and add "STD".
The aim is to copy the following pdf and also keep the "embeddedness" structure of the pdf (i.e. Albania-Total Debt-Short Term Debt- Official creditior) so that STATA can use that easily this is the pdf
Has anyone ever done something like this?
Thanks in advance!
All the best,
Greg
If I understand you correctly, then I think you can use the following:
Public Sub Main()
Dim lRow As Long
Dim lLoop As Long
For lRow = 1 To Cells(Rows.Count, 1).End(xlUp).Row
If InStr(1, LCase(Cells(lRow, 1)), "total debt stock") > 0 Then
For lLoop = 1 To 6
Cells(lRow + lLoop, 1) = "TDS-" & Cells(lRow + lLoop, 1)
Next lLoop
lRow = lRow + 6
End If
If InStr(1, LCase(Cells(lRow, 1)), "short-term debt") > 0 Then
For lLoop = 1 To 2
Cells(lRow + lLoop, 1) = "STD-" & Cells(lRow + lLoop, 1)
Next lLoop
lRow = lRow + 2
End If
Next lRow
End Sub
For testing if a cell "contains" either Total Debt Stock or Short-term debt, I change everything to lowercase, so you might want to change that. I also added a hyphen after "TDS" and "STD".
I am trying to combine several worksheets into one worksheet via VBA to resolve a matrix type into a pivot friendly form. This works nicely so far, except for the fact that after each loop one additional line gets appendended.
Here is what I get:
Result
And this is what i would like to have:
Desired outcome
Public Sub CopyData()
Dim iRowCount, iTableCount, iRowCountTarget, iColumnCount, iRowCountUser, iWorksheetsCounter, iNumberOfWorksheets As Integer
Application.ScreenUpdating = False
iColumnCount = 2
iRowCountUser = 1
iWorksheetsCounter = 1
iNumberOfWorksheets = ThisWorkbook.Worksheets.Count - 1
iTableCount = WorksheetFunction.CountA(Range("A:A"))
iTableCountTarget = WorksheetFunction.CountA(ActiveWorkbook.Worksheets(iNumberOfWorksheets + 1).Range("A:A"))
For iWorksheetsCounter = 1 To iNumberOfWorksheets
For iRowCount = 1 To iTableCount
With ActiveWorkbook
.Worksheets(iNumberOfWorksheets + 1).Cells(iTableCountTarget + 1, 3) = ActiveWorkbook.Worksheets(iWorksheetsCounter).Cells(iRowCountUser, iColumnCount)
.Worksheets(iWorksheetsCounter).Cells(iRowCount + 1, 1).Copy
.Worksheets(iNumberOfWorksheets + 1).Cells(iTableCountTarget + 1, 1).PasteSpecial
.Worksheets(iWorksheetsCounter).Cells(iRowCount + 1, 2).Copy
.Worksheets(iNumberOfWorksheets + 1).Cells(iTableCountTarget + 1, 2).PasteSpecial
.Worksheets(iNumberOfWorksheets + 1).Cells(iTableCountTarget + 1, 4) = iTableCountTarget
End With
iTableCountTarget = iTableCountTarget + 1
Next iRowCount
Next iWorksheetsCounter
Application.ScreenUpdating = True
End Sub
where am I adding the additional line? I cannot seem to get around it.
thanks for all the pointers!
EDIT: Added a picture of the source table upon request.
All tables should be the same size, but I might want to extend that to more columns in individual tables later down the line
Source Table(s)
Another way to do it :
Dim oWs, oFinalWs As Worksheet
Dim finalLastRow As Integer
Set oFinalWs = ThisWorkbook.Worksheets("final")
oFinalWs.Cells.ClearContents
For Each oWs In ThisWorkbook.Worksheets
If Not oWs.Name = oFinalWs.Name Then
finalLastRow = oFinalWs.Cells(oFinalWs.Cells.Rows.Count, 1).End(xlUp).Row
oWs.Cells(1, 1).CurrentRegion.Copy oFinalWs.Cells(finalLastRow, 1)
End If
Next
I have an excel spreadsheet. In a column of the spreadsheet I have a list of codes (numbers).These codes (numbers) are sorted from highest to lowest values.(some of these codes has been repeated. For example I have three consecutive line with code 1001200).I want to insert new rows between each codes (in case of having repeated codes i just need one new row (for example i Just need one new row for 1001200 not 3 rows) .
I have written the following code but it does not work.
Sub addspace()
Dim space_1(5000), Space_2(5000)
For n = 1 To 5000
Debug.Print space_1(n) = Worksheets("sheet3").Cells(1 + n, 1).Value
Debug.Print Space_2(n) = Worksheets("sheet3").Cells(2 + n, 1).Value
Next
For n = 1 To 5000
If space_1(n) <> Space_2(n) Then
Range("space_1(n)").EntireRow.Insert
End If
Next
End Sub
How can I fix it? (From the code you can see that I am so beginner :)))
Cheers
To insert one empty row between each unique value try this:
Option Explicit
Public Sub addspace()
Dim i As Long
Application.ScreenUpdating = False
With Worksheets("sheet3")
For i = 5000 To 2 Step -1
While .Range("A" & i - 1) = .Range("A" & i)
i = i - 1
Wend
.Rows(i).Insert Shift:=xlDown
Next
End With
Application.ScreenUpdating = True
End Sub
It starts from the end row and moves up, skipping duplicates
The Range("space_1(n)") is invalid. Arg of range object should be a column name like "A1", you can use Range("A" & n).EntireRow.Insert in your code. But I recommend my code.
Please try,
Sub addspace()
Dim n As Integer
For n = 1 To 5000
If Worksheets("sheet3").Cells(n, 1).Value <> Worksheets("sheet3").Cells(n + 1, 1).Value Then
Worksheets("sheet3").Cells(n + 1, 1).EntireRow.Insert
n = n + 1
End If
Next
End Sub
I haven't seen this addressed yet, but I think that might be because I don't know how to phrase my problem concisely. Here's an example of what I'd like to try and do:
Given a column which holds state initials check output sheet if that state has been found before. If it hasn't then populate a new cell with that state's initials and initialize the count (number of times state has been found) to one. If the state's initials are found in a cell within the output sheet then increment the count by one.
With this, if we have a 50,000 (or however many) lined excel sheet that has states in random order (states may or may not be repeated) we will be able to create a clean table which outputs which states are in the raw data sheet and how many times they appeared. Another way to think about this is coding a pivot table, but with less information.
There's a couple of ways that I've thought about how to complete this, I personally think none of these are very good ideas but we'll see.
Algorithm 1, all 50 states:
Create 50 string variables for each state, create 50 long variables for the counts
Loop through raw data sheet, if specific state found then increment appropriate count (this would require 50 if-else statements)
Output results
Overall..... terrible idea
Algorithm 2, flip-flop:
Don't create any variables
If a state is found in raw data sheet , look in output sheet to check if state has been found before
If state has been found before, increment cell adjacent by one
If state has not been found before, change next available blank cell to state initials and initialize cell adjacent to one
Go back to raw data sheet
Overall..... this could work, but I feel as if it would take forever, even with raw data sheets that aren't very big but it has the benefit of not wasting memory like the 50 states algorithm and less lines of code
On a side note, is it possible to access a workbook's (or worksheet's) cells without activating that workbook? I ask because it would make the second algorithm run much quicker.
Thank you,
Jesse Smothermon
A couple of point that will speed up your code:
You don't need to active workbooks, worksheets or ranges to access them
eg
DIM wb as workbook
DIM ws as worksheet
DIM rng as range
Set wb = Workbooks.OpenText(Filename:=filePath, Tab:=True) ' or Workbooks("BookName")
Set ws = wb.Sheets("SheetName")
Set rng = ws.UsedRange ' or ws.[A1:B2], or many other ways of specifying a range
You can now refer to the workbook/sheet/range like
rng.copy
for each cl in rng.cells
etc
Looping through cells is very slow. Much faster to copy the data to a variant array first, then loop through the array. Also, when creating a large amount of data on a sheet, better to create it in a variant array first then copy it to the sheet in one go.
DIM v As Variant
v = rng
eg if rng refers to a range 10 rows by 5 columns, v becomes an array of dim 1 to 10, 1 to 5. The 5 minutes you mention would probably be reduced to seconds at most
Sub CountStates()
Dim shtRaw As Excel.Worksheet
Dim r As Long, nr As Long
Dim dict As Object
Dim vals, t, k
Set dict = CreateObject("scripting.dictionary")
Set shtRaw = ThisWorkbook.Sheets("Raw")
vals = Range(shtRaw.Range("C2"), _
shtRaw.Cells(shtRaw.Rows.Count, "C").End(xlUp)).Value
nr = UBound(vals, 1)
For r = 1 To nr
t = Trim(vals(r, 1))
If Len(t) = 0 Then t = "Empty"
dict(t) = dict(t) + 1
Next r
For Each k In dict.keys
Debug.Print k, dict(k)
Next k
End Sub
I implemented my second algorithm to see how it would work. The code is below, I did leave out little details in the actual problem to try and be more clear and get to the core problem, sorry about that. With the code below I've added the other "parts".
Code:
' this number refers to the raw data sheet that has just been activated
totalRow = ActiveSheet.Range("A1").End(xlDown).Row
For iRow = 2 To totalRow
' These are specific to the company needs, refers to addresses
If (ActiveSheet.Cells(iRow, 2) = "BA") Then
badAddress = badAddress + 1
ElseIf (ActiveSheet.Cells(iRow, 2) = "C") Then
coverageNoListing = coverageNoListing + 1
ElseIf (ActiveSheet.Cells(iRow, 2) = "L") Then
activeListing = activeListing + 1
ElseIf (ActiveSheet.Cells(iRow, 2) = "NC") Then
noCoverageNoListing = noCoverageNoListing + 1
ElseIf (ActiveSheet.Cells(iRow, 2) = "NL") Then
inactiveListing = inactiveListing + 1
ElseIf (ActiveSheet.Cells(iRow, 2) = "") Then
noHit = noHit + 1
End If
' Algorithm beginning
' If the current cell (in state column) has something in it
If (ActiveSheet.Cells(iRow, 10) <> "") Then
' Save value into a string variable
tempState = ActiveSheet.Cells(iRow, 10)
' If this is also in a billable address make variable true
If (ActiveSheet.Cells(iRow, 2) = "C") Or (ActiveSheet.Cells(iRow, 2) = "L") Or (ActiveSheet.Cells(iRow, 2) = "NL") Then
boolStateBillable = True
End If
' Output sheet
BillableWorkbook.Activate
For tRow = 2 To endOfState
' If the current cell is the state
If (ActiveSheet.Cells(tRow, 9) = tempState) Then
' Get the current hit count of that state
tempStateTotal = ActiveSheet.Cells(tRow, 12)
' Increment the hit count by one
ActiveSheet.Cells(tRow, 12) = tempStateTotal + 1
' If the address was billable then increment billable count
If (boolStateBillable = True) Then
tempStateBillable = ActiveSheet.Cells(tRow, 11)
ActiveSheet.Cells(tRow, 11) = tempStateBillable + 1
End If
Exit For
' If the tempState is unique to the column
ElseIf (tRow = endOfState) Then
' Set state, totalCount
ActiveSheet.Cells(tRow - 1, 9) = tempState
ActiveSheet.Cells(tRow - 1, 12) = 1
' Increment the ending point of the column
endOfState = endOfState + 1
' If it's billable, indicate with number
If (boolStateBillable = True) Then
tempStateBillable = ActiveSheet.Cells(tRow - 1, 11)
ActiveSheet.Cells(tRow - 1, 11) = tempStateBillable + 1
End If
End If
Next
' Activate raw data workbook
TextFileWorkbook.Activate
' reset boolean
boolStateBillable = False
Next
I ran it once and it seems to have worked. The problem is that it took roughly five minutes or so, the original code takes 0.2 (rough guess). I think the only way to make the code perform quicker is to somehow be able to not activate the two workbooks over and over. This means that the answer is not complete but I will edit if I figure out the rest.
Note I will revisit pivot tables to see if I can do everything that I need to in them, as of now it looks like there are a couple of things that I won't be able to change but I'll check
Thank you,
Jesse Smothermon
I kept with the second algorithm. There is the dictionary option that I forgot but I'm still not very comfortable with how it works and I generally don't understand it quite yet. I played with the code for a bit and changed some thing up, it now works faster.
Code:
' In output workbook (separate sheet)
Sheets.Add.Name = "Temp_Text_File"
' Opens up raw data workbook (originally text file
Application.DisplayAlerts = False
Workbooks.OpenText Filename:=filePath, Tab:=True
Application.DisplayAlerts = True
Set TextFileWorkbook = ActiveWorkbook
totalRow = ActiveSheet.Range("A1").End(xlDown).Row
' Copy all contents of raw data workbook
Cells.Select
Selection.Copy
BillableWorkbook.Activate
' Paste raw data into "Temp_Text_File" sheet
Range("A1").Select
ActiveSheet.Paste
ActiveWorkbook.Sheets("Billable_PDF").Select
' Populate long variables
For iRow = 2 To totalRow
If (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "BA") Then
badAddress = badAddress + 1
ElseIf (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "C") Then
coverageNoListing = coverageNoListing + 1
ElseIf (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "L") Then
activeListing = activeListing + 1
ElseIf (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "NC") Then
noCoverageNoListing = noCoverageNoListing + 1
ElseIf (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "NL") Then
inactiveListing = inactiveListing + 1
ElseIf (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "") Then
noHit = noHit + 1
End If
If (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 10) <> "") Then
tempState = ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 10)
If (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "C") Or (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "L") Or (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "NL") Then
boolStateBillable = True
End If
'BillableWorkbook.Activate
For tRow = 2 To endOfState
If (ActiveSheet.Cells(tRow, 9) = tempState) Then
tempStateTotal = ActiveSheet.Cells(tRow, 12)
ActiveSheet.Cells(tRow, 12) = tempStateTotal + 1
If (boolStateBillable = True) Then
tempStateBillable = ActiveSheet.Cells(tRow, 11)
ActiveSheet.Cells(tRow, 11) = tempStateBillable + 1
End If
Exit For
ElseIf (tRow = endOfState) Then
ActiveSheet.Cells(tRow, 9) = tempState
ActiveSheet.Cells(tRow, 12) = 1
endOfState = endOfState + 1
If (boolStateBillable = True) Then
tempStateBillable = ActiveSheet.Cells(tRow, 11)
ActiveSheet.Cells(tRow, 11) = tempStateBillable + 1
End If
End If
Next
'stateOneTotal = stateOneTotal + 1
'If (ActiveSheet.Cells(iRow, 2) = "C") Or (ActiveSheet.Cells(iRow, 2) = "L") Or (ActiveSheet.Cells(iRow, 2) = "NL") Then
' stateOneBillable = stateOneBillable + 1
'End If
'ElseIf (ActiveSheet.Cells(iRow, 10) = "FL") Then
'stateTwoTotal = stateTwoTotal + 1
'If (ActiveSheet.Cells(iRow, 2) = "C") Or (ActiveSheet.Cells(iRow, 2) = "L") Or (ActiveSheet.Cells(iRow, 2) = "NL") Then
' stateTwoBillable = stateTwoBillable + 1
'End If
End If
'TextFileWorkbook.Activate
If (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "C") Or (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "L") Or (ActiveWorkbook.Sheets("Temp_Text_File").Cells(iRow, 2) = "NL") Then
billableCount = billableCount + 1
End If
boolStateBillable = False
Next
' Close raw data workbook and raw data worksheet
Application.DisplayAlerts = False
TextFileWorkbook.Close
ActiveWorkbook.Sheets("Temp_Text_File").Delete
Application.DisplayAlerts = True
Thank you for the comments and suggestions. It is very much appreciated as always.
Jesse Smothermon
I am looking to find some help on this Macro.. The idea is, upon execution the Macro will pull The Data from a Web Page (I.E http://www.link.com/id=7759) and place it into let's say Sheet2, and then Open up Page 2, and place it right below Page 1's Data in Sheet 2.... And So on and So on until a set Page Number.. Ideally I would like it just to pull The following in order;
Title
Artist
Type
Paper Size
Image Size
Retail Prize
Quantity
And further more it is ideal that is placed in proper columns and rows of 4 and 8 Rows down(Columns Across just like in the web page).
Any help on this would be greatly, greatly appreciated. I have done some research and found similar macros, sadly have had no luck getting them to work for me. Mainly VB's fail to go through as well.
Bit of useful info (maybe) I figured this out when I was trying to write my own, maybe it will save who ever helps some time..
.WebTables = "8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38"
Those are the tables for each item I want to put into the Que...
Here's a sample method to get you going
Based on a few assumptions
Workbook contains a Sheet to hold query data called "Query"
Workbook contains a Sheet to put the data in called "AllData"
All old data is removed on running the macro
I think you need to include Table 7 in the qyuery
Pages to process is hard coded as For Pg = 1 To 1 , change this to suit
.
Sub QueryWebSite()
Dim shQuery As Worksheet, shAllData As Worksheet
Dim clData As Range
Dim qts As QueryTables
Dim qt As QueryTable
Dim Pg As Long, i As Long, n As Long, m As Long
Dim vSrc As Variant, vDest() As Variant
' setup query
Set shQuery = ActiveWorkbook.Sheets("Query")
Set shAllData = ActiveWorkbook.Sheets("AllData")
'Set qt = shQuery.QueryTables(1)
On Error Resume Next
Set qt = shQuery.QueryTables("Liebermans")
If Err.Number <> 0 Then
Err.Clear
Set qt = shQuery.QueryTables.Add( _
Connection:="URL;http://www.liebermans.net/productlist.aspx?id=7759&page=1", _
Destination:=shQuery.Cells(1, 1))
With qt
.Name = "Liebermans"
.WebSelectionType = xlSpecifiedTables
.WebFormatting = xlWebFormattingNone
.WebTables = "7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38"
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
.Refresh BackgroundQuery:=False
End With
End If
On Error GoTo 0
i = InStr(qt.Connection, "&page=")
' clear old data
shAllData.UsedRange.ClearContents
shAllData.Cells(1, 1) = "Title"
shAllData.Cells(1, 2) = "Artist"
shAllData.Cells(1, 3) = "Type"
shAllData.Cells(1, 4) = "Paper Size"
shAllData.Cells(1, 5) = "Image Size"
shAllData.Cells(1, 6) = "Price"
shAllData.Cells(1, 7) = "Quantity"
m = 0
ReDim vDest(1 To 10000, 1 To 7)
For Pg = 1 To 1
' Query Wb site
qt.Connection = Left(qt.Connection, i + 5) & Pg
qt.Refresh False
' Process data
vSrc = qt.ResultRange
n = 2
Do While n < UBound(vSrc, 1)
If vSrc(n, 1) <> "" And vSrc(n - 1, 1) = "" Then
m = m + 1
vDest(m, 1) = vSrc(n, 1)
End If
If vSrc(n, 1) Like "Artist:*" Then vDest(m, 2) = Trim(Mid(vSrc(n, 1), 8))
If vSrc(n, 1) Like "Type:*" Then vDest(m, 3) = Trim(Mid(vSrc(n, 1), 6))
If vSrc(n, 1) Like "Paper Size:*" Then vDest(m, 4) = Trim(Mid(vSrc(n, 1), 12))
If vSrc(n, 1) Like "Image Size:*" Then vDest(m, 5) = Trim(Mid(vSrc(n, 1), 12))
If vSrc(n, 1) Like "Retail Price:*" Then vDest(m, 6) = Trim(Mid(vSrc(n, 1), 14))
If vSrc(n, 1) Like "Quantity in stock:*" Then vDest(m, 7) = Trim(Mid(vSrc(n, 1), 19))
n = n + 1
Loop
Next
' Put data in sheet
shAllData.Cells(2, 1).Resize(m, 7) = vDest
End Sub